• 51nod 1126 求递推序列的第N项 思路:递推模拟,求循环节。详细注释


    题目:

    看起来比较难,范围10^9 O(n)都过不了,但是仅仅是看起来。(虽然我WA了7次 TLE了3次,被自己蠢哭)

    我们观察到 0 <= f[i] <= 6 就简单了,就像小学初中学的找到循环节然后求第n项。

    我们只用记录下两个连续的数字重复出现,就找到了循环节,然后就简单了。

    注意:MOD函数是用于返回两数相除的余数,返回结果的符号与除数(divisor)的符号相同。(来自百度百科) ,mod结果正负所以要与7正负相同。

    代码(详细注释):

    #include <bitsstdc++.h>
    using namespace std;
    typedef long long ll;
    
    int f[10000];  // 存递推项。
    int v[10][10]; // v[i][j]表示 f[k-1]和f[k]出现的位置,第二次出现就找到了循环节了。
    int main() {
        int a,b,n;
        cin >> a >> b >> n;
        int round ;  // 循环节长度
        f[1] = f[2] = 1;
        v[1][1] = 1;  // 1,1连续出现的位置是1
        int start;    // 循环节开始的位置-1。
        for(int i = 3;; i++){
            f[i] = ((a*f[i-1] + b*f[i-2])%7+7)%7;  // 让f[i]变成成正数。
    //        cout << "i: " << i << " f: " << f[i] << endl;
            if(i == n){
                cout << f[i] << endl; // 如果求出循环节之前求出了答案,直接输出。
                return 0;
            }
            if(v[f[i-1]][f[i]] == 0){
                v[f[i-1]][f[i]] = i-1;  // f[i-1],f[i]第一次出现
            }else{ 
                // 第二次出现
                round = i-1-v[f[i-1]][f[i]];   // 循环节长度
                start = v[f[i-1]][f[i]]-1;   // 循环节开始的位置-1。
                break;
            }
        }
        n -= start;  // 减去不在循环节之内的部分。
        n = n % round;  // 求出n在循环节中的位置。
        
        //已知的循环节从 start+1 - start+round。
        if(n == 0) cout << f[start+round] << endl; 
        else cout << f[start+n] << endl;
        return 0;
    }
    //written by zhangjiuding.
  • 相关阅读:
    Android 动态注册JNI函数
    Zero-shot Learning / One-shot Learning / Few-shot Learning
    英语科技论文表述中常用的时态
    GraphHopper-初识
    CentOS7 Python3下安装 TensorToolbox 1.0.22时的一些错误及解决办法
    e.g. i.e. etc. et al. w.r.t. i.i.d.英文论文中的缩写语
    Pytorch Tensor 常用操作
    NetworkX一个图论与复杂网络建模工具
    pytorch1.0实现RNN for Regression
    pytorch1.0实现RNN-LSTM for Classification
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/7445743.html
Copyright © 2020-2023  润新知