ACM—Number Sequence(HDOJ1005)

原題連接: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]。

相關文章
相關標籤/搜索