import java.util.*;
public class AlmostPerfect {
public static void main(String[] args) {
Scanner x = new Scanner(System.in);
while(x.hasNext()){
int n = x.nextInt();
int sum = recursion(n,n-1,0);
if (sum == n) {
System.out.println(n + " perfect");
} else if ((n - sum) <= 2) {
System.out.println(n + " almost perfect");
} else {
System.out.println(n + " not perfect");
}
}
}
public static int recursion(int n, int x,int sum) {
if(x==0){
return sum;
}
else if (n % x == 0) {
sum+=x;
return recursion(n,x-1,sum);
}
else{
return recursion(n,x-1,sum);
}
}
}
我想从根本上找到解决方案的问题...存在解决方案,但我无法理解超出内存限制的属性。 问题链接:https://open.kattis.com/problems/almostperfect 谢谢。
答案 0 :(得分:0)
如果您必须使用递归解决方案,则可以将递归的深度限制为
避免堆栈溢出。
您可以在连续的时间间隔(一次为一个时间间隔)上运行递归解决方案:
import java.util.stream.IntStream;
public class AlmostPerfect {
//defines the recursive iteration depth. increase it and you run into
//stack over flow
private static int RECURSION_DEPTH =5000;
public static void main(String[] args) {
//run comparison test between recursive and non recursive solutions
IntStream.range(1,200000).forEach(i ->{
double sumRecursive = recursionWithLimitedDepth(i);
double sumIterative = iterative(i);
if((sumRecursive != sumIterative)) {
System.out.println("for "+ i +" "+ sumRecursive + "<>" +sumIterative );
return;
}
if((i%20000) ==0) {
System.out.println("20,000 numbers successfully checked" );
}
});
System.out.println("Test finished");
}
//helper method for recursive solution
public static double recursionWithLimitedDepth(int n) {
double sum = 0;
int rangeStart = n-1;
int rangeEnd = rangeStart - RECURSION_DEPTH;
while (rangeStart > 0) {
sum += recursionWithLimitedDepth(n, rangeStart, rangeEnd, 0);
rangeStart = (rangeEnd - 1) >= 0 ? rangeEnd - 1 : 0;
rangeEnd = (rangeStart - RECURSION_DEPTH) >= 0 ? rangeStart - RECURSION_DEPTH :0;
}
return sum;
}
//run recursive solution on a limited range defined by rangeStart, rangeEnd
public static double recursionWithLimitedDepth(int numberToTest, int rangeStart,
int rangeEnd , double sum) {
if(rangeStart == 0){
return sum;
}
else if ((numberToTest % rangeStart) == 0) {
sum+=rangeStart;
}
if(rangeStart == rangeEnd){
return sum;
}
return recursionWithLimitedDepth(numberToTest,rangeStart-1, rangeEnd, sum);
}
//simple iterative to test against
public static double iterative(int n) {
double sum = 0;
for(int x = n-1; x > 0; x--) {
if((n%x) == 0) {
sum += x;
}
}
return sum;
}
}
请注意,sum
是double
,以避免Integer
溢出(已通过Integer.MAX_VALUE
测试)。