• 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]。

  • 相关阅读:
    快速启动jar包脚本【Linux】
    解决Linux报错:/bin/bash^M: 坏的解释器: 没有那个文件或目录
    学习——nginx(2021/09/23)
    react hook中的状态管理方式
    findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of DomWrapper which is inside StrictMode.
    祝胡老师节日快乐
    vue3+ts+AntV/L7加载钻取地图
    实用的 Bash 快捷键
    react antd form 自定义表单验证validator 需要注意的细节,否则会无法触发表单提交。
    execjs
  • 原文地址:https://www.cnblogs.com/PerkinsZhu/p/6266715.html
Copyright © 2020-2023  润新知