zoukankan      html  css  js  c++  java
  • ACM—Number Sequence(HDOJ1005)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 

    主要内容:

      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).

    看到这样的公式很容易想到递归调用求解,但是在本题中n的取值范围:1<n>100000000,因此很容易报出栈溢出。因此,递归放弃。

    然后便考虑到通过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,没办法换新方法。

    想来想去没想到,最终看到acmer谈到在49次之后会发生循环,具体代码如下:

    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通过,便想为何会发生循环?

     ***********************************************************************

    对7求摩决定了sum[i]的范围必定在0~6之间。然后又因为在A和B确定的前提下,sum[i]的值由sum[i-1]和sum[i-2]来决定的。

    sum[i-1]和sum[i-2]的组合情况最多有7*7=49种。所有的组合情况必定在这49种范围内找到相同的。

    需要注意的是,由于A和B的不同,在循环体中可能并不一定包含49种各种情况,可能只有部分情况包含在循环体内。如:

    14种情况包含在循环体内(A=5,B=6)

    4、5、0、2、3、6、6、3、2、0、5、4、1、1、4、5、0、2、3、6、6、3、2、0、5、4、1、1、4、5、0、2、3、6、6、3、2、0、5、4、1、1、4、5、0、2、3、6、
    6、3、2、0、5、4、1、1、4、5、0、2、3、6、6、3、2、0、5、4、1、1、4、5、0、2、3、6、6、3、2、0、5、4、1、1、4、5、0、2、3、6、6、3、2、0、5、4、

     16种情况包含在循环体内(A=1,B=1)

    2、3、5、1、6、0、6、6、5、4、2、6、1、0、1、1、2、3、5、1、6、0、6、6、5、4、2、6、1、0、1、1、2、3、5、1、6、0、6、6、5、4、2、6、1、0、1、1、
    2、3、5、1、6、0、6、6、5、4、2、6、1、0、1、1、2、3、5、1、6、0、6、6、5、4、2、6、1、0、1、1、2、3、5、1、6、0、6、6、5、4、2、6、1、0、1、1、

    44种情况包含在循环体内(A=89564,B=185421)

    4、1、5、0、4、3、3、5、3、1、0、5、2、2、1、2、3、0、1、6、6、3、6、2、0、3、4、4、2、4、6、0、2、5、5、6、5、4、0、6、1、1、4、1、5、0、4、3、
    3、5、3、1、0、5、2、2、1、2、3、0、1、6、6、3、6、2、0、3、4、4、2、4、6、0、2、5、5、6、5、4、0、6、1、1、4、1、5、0、4、3、3、5、3、1、0、5、

     至于哪种情况会把49种全部包括就不知道了,但是可以肯定的是,这49个数中循环体的个数必定大于等于1。

     所以在进行求和处理的时候对49进行了取摩  sum[n % 49]。

  • 相关阅读:
    Django(app的概念、ORM介绍及编码错误问题)
    Django(完整的登录示例、render字符串替换和redirect跳转)
    Construct Binary Tree from Preorder and Inorder Traversal
    Single Number II
    Single Number
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Binary Tree Zigzag Level Order Traversal
    Recover Binary Search Tree
    Add Binary
  • 原文地址:https://www.cnblogs.com/PerkinsZhu/p/6266715.html
Copyright © 2011-2022 走看看