zoukankan      html  css  js  c++  java
  • 杭电 1005

    Number Sequence

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 157162    Accepted Submission(s): 38477


    Problem Description
    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).
     
    Input
    The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
     
    Output
    For each test case, print the value of f(n) on a single line.
     
    Sample Input
    1 1 3
    1 2 10
    0 0 0
     
    Sample Output
    2
    5
     
    此题不肯能将每一种情况都记录下来,考虑mod7之后,有0,1,2,3,4,5,6   7种情况,则对每一种a,b, f(n)必然构成了一个循环队列
    由于f(n)是f(n-1)和f(n-2)的线性组合,故f(n)最多可能有7*7 = 49种情况,若让f(n)一直不出现重复,那么这个循环队列的最大长度必然是49,超过这个长度这个队列就一定会出现重复,这有点类似于鸽巢原理。
     
    所以对于给定的a,b,   我们可以利用一个长度稍大于49的数组记录结果。
    然后去寻找队列的最长不重复的子序列,只要发现序列中某个相邻两项和后面某个相邻两项完全相同,则确定出现重复。
    代码如下
     
     1 #include <cstdio>
     2 #include <cstdlib>
     3 int res[55];
     4 
     5 int main(int argc, char const *argv[])
     6 {
     7     int a, b, n;
     8     while(scanf("%d %d %d",&a,&b,&n),a|b|n) {
     9         res[1] = 1;
    10         res[2] = 1;
    11         int flag = 0;    
    12         int from,to;
    13         for(int i = 3; i <= n && !flag; i++) {
    14             res[i] = (a * res[i-1] + b *res[i-2])%7;
    15             for(int j = 2; j <= i-1; j++) {
    16                 if(res[i] == res[j] && res[i-1] && res[j-1]) {
    17                     flag = 1;
    18                     from = j;
    19                     to = i;
    20                     break;
    21                 }
    22             }
    23         }
    24         int ans;
    25         if(flag) {
    26             ans = res[from+(n-to)%(to-from)];
    27         }
    28         else {
    29             ans = res[n];
    30         }
    31         printf("%d
    ",ans);
    32     }
    33     return 0;
    34 }

    注:第8行,逗号 把最后一个表达式的值当作返回值

    比如

    int i;
    while( scanf("%d",&i) , i != 0 )
    {
    }
    这里的,是一个序点
    含义是必须先完成前面的求值(scanf("%d",&i) 的求值,但这里其实我们要的是给i赋值的副效应,scanf("%d",&i)这个表达式的值是没有用的 ),然后再进行右面的求值
    所以,逗号表达式尽管只用到最后一个值,但很可能最后一个值依赖于前面求值引起的副效应
    这就是为什么要写前面子表达式的原因,也是逗号表达式的真正意义
    
    
    
    作者:薛非
    链接:https://www.zhihu.com/question/22710102/answer/22455046
    来源:知乎
    著作权归作者所有,转载请联系作者获得授权。
  • 相关阅读:
    上传github代码
    git 代码更新
    linux 遇见的问题
    How to stop pycharm show files in project in red color?
    Linux下动态库查找路径的问题
    centos7 建立虚拟目录
    [BZOJ3747] Kinoman
    [BZOJ2169] 连边
    [洛谷P4251] 小凸玩矩阵
    [洛谷P2764] 最小路径覆盖
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5999473.html
Copyright © 2011-2022 走看看