【模拟】【打表】【120814测试】【NOIP第二次模拟赛】无聊的游戏
3.无聊的游戏(boring.pas/c/cpp)
【题目描述】
有一个很无聊的游戏,就是——根据递推公式计算数列
没错,这道题就是这么无聊!
给你数列f(0)=1, f(n)=f(n-1)^2+1 (n > 0)
求出f(n)
(既然题目已经这么无聊了,那就不让大家写高精度了,取个模好了)
【输入格式】
一个整数n
【输出格式】
一行一个整数f(n),结果对1200007取模
【样例输入】
3
【样例输出】
26
【数据规模】
10%数据 1<=n<=10
30%数据 1<=n<=10^6
100%数据 1<=n<=10^9
【时限】
1s
①如果你直接按题目暴力能拿30分
②遇到这种按公式,并且是由前一个推当前的(即由f[i-1]推f[i]的)那么就可以想到打表!这个也能得100分
不过由于数据太庞大,就只能部分打表(即每隔100w打一个数,然后写到你自己程序的数组里),完了后就该写自己的程序了,直接用n/100w找到是哪个循环节,然后只需向后推n%100w次即可,这样最坏的情况也就是退了100w次!很轻松就过了
③不过要想代码简洁点,也要用到上面的打表,然后写一个程序找到循环节,也能得100分
这个打表出来了,你想凭肉眼看出循环节,可能不大现实(除非你是神牛。。。),所以还需要借助程序,在写一个程序,把刚才的表当做输入文件,每读一个数,就hash标记一下,后面只要遇到一个已经标记的数,那么这之间必定是循环的!
具体的打表我会在后面写一个打表专题,只需在标签那里找到“打表”即可
这里我已经找出来循环节:从803开始循环,570为一个周期
C++ Code
#include<iostream> using namespace std; const int mod=1200007; int n; long long f[1500]; int main() { freopen("boring.in","r",stdin); freopen("boring.out","w",stdout); cin>>n; int i; f[0]=1; for(i=1;i<=1500;i++) { f[i]=((f[i-1]*f[i-1])%mod+1)%mod; if(i==n) { cout<<f[n]; exit(0); } } n=(n-802)%570; if(n==0)n+=570; n+=802; cout<<f[n]; return 0; }
..... 转载请注明出处 ..... http://oijzh.cnblogs.com ..... by jiangzh