题意:
给原始序列1
给定变化规则是,对于原来的序列每一个0前边插入1,每个1前边插入0.
问原始序列经过n次变化之后有多少对相邻的0.
规律题:
从第二次开始
当第奇数次变化之后,数量变成原来数量的两倍-1;
当第偶数次变化之后,数量变成原来数量的两倍+1;
但是由于数据2^1000次方太大,需要用到大数,屌丝还没学到java对大数的处理,所以只写了一个高精度。
/************************************************************************* > File Name: C.cpp > Author: ttpond > Created Time: 2015-8-22 15:32:30 ************************************************************************/ #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<math.h> #include<vector> #include<map> #include<queue> #include<stack> #include<set> using namespace std; char dp[1005][1005]; void cal(int pos) { int len=strlen(dp[pos-1]); int mm[1005]; memset(mm,0,sizeof(mm)); int tmp; for(int i=0;i<len;i++) { mm[i]+=(dp[pos-1][i]-48)*2; mm[i+1]+=mm[i]/10; mm[i]=mm[i]%10; } for(int i=0;i<len+1;i++) { dp[pos][i]=mm[i]+48; } if(dp[pos][len]=='0') dp[pos][len]=0; } void add(int pos) { int len=strlen(dp[pos]); int tmp; int mm[1005]; memset(mm,0,sizeof(mm)); mm[0]=1; for(int i=0;i<len;i++) { mm[i]+=dp[pos][i]-48; mm[i+1]=mm[i]/10; mm[i]=mm[i]%10; } for(int i=0;i<len+1;i++) { dp[pos][i]=mm[i]+48; } if(dp[pos][len]=='0') dp[pos][len]=0; } void sub(int pos) { int len=strlen(dp[pos]); int mm[1005]; memset(mm,0,sizeof(mm)); mm[0]=-1; for(int i=0;i<len;i++) { mm[i]+=dp[pos][i]-48; if(mm[i]<0) { mm[i]+=10; mm[i+1]--; } } for(int i=0;i<len;i++) { dp[pos][i]=mm[i]+48; } if(dp[pos][len-1]=='0') dp[pos][len-1]=0; } int main() { memset(dp,0,sizeof(dp)); dp[1][0]='0'; dp[2][0]='1'; dp[3][0]='1'; bool st=0; for(int i=4;i<=1000;i++) { cal(i); if(!st) { add(i); } else { sub(i); } st=!st; } int n; while(scanf("%d",&n)!=EOF) { int len=strlen(dp[n]); for(int i=len-1;i>=0;i--) { printf("%c",dp[n][i]); } printf("\n"); } }