HDU 1041 Computer Transformation

解题报告:这题的意思是一开始电脑中有一个1,现在定义如下规则,每经过一个步骤之后,一个1可以变为01,一个0可以变为10,所以一开始的1经过第一步的变换之后就变为01,然后01经过第二步的变换之后就变成1001,...........,现在要做的就是让你确定经过n步操作之后,里面有多少个连续的00.

我们可以这样推理,00可以经过什么样的排列得到,也就是将00反着推回去,00的上一步就是01,并且只能是01,然后01的上一步可以是一个1,也可以是00,所以地推的公式也出来了,第n步之后00的个数就是dp[n] = dp[n-2] + 2^(n-3)              (是2的n-3次方),因为dp[n-2]就是等于往前数的第二个的00的个数,然后2(n-3)就是往前数第二个的1的个数,因为第n项有2^n个数字,并且每一项的0和1的数量都是相等的,所以第n项前面两项的1的个数就是2^(n-3)。然后要注意的就是因为n最大是1000,数字会非常非常大,甚至还没有任何一种数据类型可以存储,所以就要用数组模拟,用数组模拟就涉及到了大数相加的问题,所以再写一个大数相加的函数然后再打表就可以了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<iostream>
 5 char dp[1005][505] = {"0","0","1","1"};
 6 char* add(char *x,char *y) {
 7     int a[505],b[505],c[505];
 8     int l1=strlen(x);
 9     int l2=strlen(y);
10     memset(a,0,sizeof(a));
11     memset(b,0,sizeof(b));
12     memset(c,0,sizeof(c));
13     int j=0;
14     for(int i=l1-1;i>=0;--i)
15     a[j++]=(int )x[i]-'0';
16     j=0;
17     for(int i=l2-1;i>=0;--i)
18     b[j++]=(int )y[i]-48;
19     int l=std::max(l1,l2);
20     for(int i=0;i<l;++i) {
21         c[i]=c[i]+a[i]+b[i];
22         c[i+1]+=c[i]/10;
23         c[i]%=10;
24     }
25     if(c[l]!=0)
26     l++;
27     char dd[505];
28     for(int i = 0;i<l;++i)
29     dd[i] = c[l-i-1]+'0';
30     dd[l] = NULL;
31     return dd;
32 }
33 
34 void dabiao() {
35     char c[505] = "2";
36     for(int i = 4;i<=1000;++i) {
37         strcpy(dp[i],add(dp[i-2],c));
38         strcpy(c,add(c,c));
39     }
40 }
41 int main() {
42     int n;
43     dabiao();
44     while(scanf("%d",&n)!=EOF)
45     printf("%s\n",dp[n]);
46     return 0;
47 }
View Code

 

posted @ 2013-07-17 08:30  xiaxiaosheng  阅读(347)  评论(0编辑  收藏  举报