原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 php
主要内容:spa
A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).code
看到这样的公式很容易想到递归调用求解,可是在本题中n的取值范围:1<n>100000000,所以很容易报出栈溢出。所以,递归放弃。blog
而后便考虑到经过1 to n经过for循环进行求解。代码以下:递归
public void test1005(){ Scanner in = new Scanner(System.in); while (in.hasNext()) { int A = in.nextInt(); int B = in.nextInt(); int n = in.nextInt(); if (A == 0 && B == 0 && n == 0) { return; } int sum = 0; int sumPre2 = 1; int sumPre1 = 1; if(n<3){ System.out.println(1); continue; } for (int i = 3; i <= n; i++) { sum = ((A * sumPre1) + (B * sumPre2)) % 7; sumPre2 = sumPre1; sumPre1 = sum; } System.out.println(sum); } }
没有了深层的递归,栈溢出问题解决了,可是在提交以后老是Time Limit Exceeded,没办法换新方法。get
想来想去没想到,最终看到acmer谈到在49次以后会发生循环,具体代码以下:it
public static void test1005_02(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNext()) { int A = in.nextInt(); int B = in.nextInt(); int n = in.nextInt(); if (A == 0 && B == 0 && n == 0) { return; } int[] sum = new int[49]; sum[1] = sum[2] = 1; for (int i = 3; i < 49; i++) sum[i] = ((A * sum[i - 1]) + (B * sum[i - 2])) % 7; System.out.println(sum[n % 49]); } }
AC经过,便想为什么会发生循环?for循环
***********************************************************************class
对7求摩决定了sum[i]的范围一定在0~6之间。而后又由于在A和B肯定的前提下,sum[i]的值由sum[i-1]和sum[i-2]来决定的。test
sum[i-1]和sum[i-2]的组合状况最多有7*7=49种。全部的组合状况一定在这49种范围内找到相同的。
须要注意的是,因为A和B的不一样,在循环体中可能并不必定包含49种各类状况,可能只有部分状况包含在循环体内。如:
14种状况包含在循环体内(A=5,B=6)
四、五、0、二、三、六、六、三、二、0、五、四、一、一、四、五、0、二、三、六、六、三、二、0、五、四、一、一、四、五、0、二、三、六、六、三、二、0、五、四、一、一、四、五、0、二、三、六、
六、三、二、0、五、四、一、一、四、五、0、二、三、六、六、三、二、0、五、四、一、1、四、五、0、二、三、六、六、三、二、0、五、四、一、一、四、五、0、二、三、六、六、三、二、0、五、四、
16种状况包含在循环体内(A=1,B=1)
二、三、五、一、六、0、六、六、五、四、二、六、一、0、一、一、二、三、五、一、六、0、六、六、五、四、二、六、一、0、一、一、二、三、五、一、六、0、六、六、五、四、二、六、一、0、一、一、
二、三、五、一、六、0、六、六、五、四、二、六、一、0、一、一、二、三、五、一、六、0、六、六、五、四、二、六、一、0、一、一、二、三、五、一、六、0、六、六、五、四、二、六、一、0、一、一、
44种状况包含在循环体内(A=89564,B=185421)
四、一、五、0、四、三、三、五、三、一、0、五、二、二、一、二、三、0、一、六、六、三、六、二、0、三、四、四、二、四、六、0、二、五、五、六、五、四、0、六、一、1、四、一、五、0、四、三、
三、五、三、一、0、五、二、二、一、二、三、0、一、六、六、三、六、二、0、三、四、四、二、四、六、0、二、五、五、六、五、四、0、六、一、一、四、一、五、0、四、三、三、五、三、一、0、五、
至于哪一种状况会把49种所有包括就不知道了,可是能够确定的是,这49个数中循环体的个数一定大于等于1。
因此在进行求和处理的时候对49进行了取摩 sum[n % 49]。