Bzoj2656 [Zjoi2012]数列(sequence)
Submit: 1448 Solved: 762
[Submit][Status][Discuss]
Description
小白和小蓝在一起上数学课,下课后老师留了一道作业,求下面这个数列的通项公式:
小白作为一个数学爱好者,很快就计算出了这个数列的通项公式。于是,小白告诉小蓝自己已经做出来了,但为了防止小蓝抄作业,小白并不想把公式公布出来。于是小白为了向小蓝证明自己的确做出来了此题以达到其炫耀的目的,想出了一个绝妙的方法:即让小蓝说一个正整数N,小白则说出 的值,如果当N很大时小白仍能很快的说出正确答案,这就说明小白的确得到了公式。但这个方法有一个很大的漏洞:小蓝自己不会做,没法验证小白的答案是否正确。作为小蓝的好友,你能帮帮小蓝吗?
Input
输入文件第一行有且只有一个正整数T,表示测试数据的组数。
第2~T+1行,每行一个非负整数N。
Output
输出文件共包含T行。
第i行应包含一个不含多余前缀0的数,它的值应等于An(n为输入数据中第i+1行被读入的整数)
【样例输入】
Sample Input
3
1
3
10
1
3
10
Sample Output
1
2
3
2
3
HINT
T<=20,N<=10^100
Source
递归+高精度
暴力递归只能解决10^8的问题
↑优化高精度无果之后,觉得应该可以找规律。
发现算奇数的时候,下面的偶数都算过了。
那么加个类似记忆化的东西就行
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 #define LL long long 9 using namespace std; 10 const int mxn=305; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 struct NUM{ 18 int len; 19 int a[mxn]; 20 friend NUM operator + (NUM a,NUM b){ 21 a.len=max(a.len,b.len); 22 for(int i=1;i<=a.len;i++){ 23 a.a[i]+=b.a[i]; 24 if(a.a[i]>9){ 25 a.a[i+1]+=a.a[i]/10; 26 a.a[i]%=10; 27 } 28 } 29 if(a.a[a.len+1])a.len++; 30 return a; 31 } 32 friend NUM operator / (NUM a,int b){ 33 for(int i=a.len;i;i--){ 34 a.a[i-1]+=(a.a[i]%b)*10; 35 a.a[i]/=b; 36 } 37 while(a.len>1 && !a.a[a.len]) a.len--; 38 return a; 39 } 40 }N,p,q; 41 void Debug(NUM x){ 42 for(int i=x.len;i;i--) 43 printf("%d",x.a[i]); 44 printf("\n"); 45 return; 46 } 47 void calc(NUM x){ 48 // NUM tmp; 49 if(x.len==1 && x.a[1]==1){ 50 p=x; 51 q.len=1;memset(q.a,0,sizeof q.a); 52 q.a[1]=1; 53 return; 54 } 55 calc(x/2); 56 if(x.a[1]&1)p=p+q; 57 else q=q+p; 58 // return tmp; 59 } 60 char s[mxn]; 61 int T; 62 int main(){ 63 // freopen("sequence.in","r",stdin); 64 // freopen("sequence.out","w",stdout); 65 T=read(); 66 int i,j; 67 p.len=1;p.a[1]=1; 68 q.len=1;q.a[1]=0; 69 while(T--){ 70 memset(N.a,0,sizeof N.a); 71 // 72 scanf("%s",s+1); 73 int len=strlen(s+1); 74 for(i=1;i<=len;i++){ 75 N.a[i]=s[len-i+1]-'0'; 76 } 77 N.len=len; 78 calc(N); 79 Debug(p); 80 } 81 return 0; 82 }
本文为博主原创文章,转载请注明出处。