【noi 2.6_9290】&【poj 2680】Computer Transformation(DP+高精度+重载运算符)

题意:给一个初始值1,每步操作将1替换为01,将0替换为10。问N步操作后有多少对连续的0。

解法:f[i]表示第i步后的答案。可以直接打表发现规律——奇数步后,f[i]=f[i-1]*2-1;偶数步后,f[i]=f[i-1]*2+1;
至于原因——我只能简单说一点。第i步后的答案可由i-1步后的“01”+“1”+“0”的个数推出,而“01”*2+“1”+“0”=01串的总个数。用x表示i-1步后的“01”的个数,则f[i]=x+(2^(i-1)-x*2);但这样复杂度挺高,我也不知道怎么优化了。

noi oj上的实际数据没有1000这么大,在65以内,用long long也可以过。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 #define N 1010
 7 
 8 int n;
 9 long long f[N];
10 
11 int main()
12 {
13     f[1]=0;
14     for (int i=2;i<=N;i++)
15     {
16       if (i%2) f[i]=f[i-1]*2-1;
17       else f[i]=f[i-1]*2+1;
18     }
19     while(~scanf("%d",&n)) printf("%lld\n",f[n]);
20     return 0;
21 }
View Code 无高精度

我高精度的不知为何在noi oj上AC,在poj上WA。若有大牛能纠正我,请多多指教~

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 #define N 1000
 7 
 8 struct node
 9 {
10     int s[210];
11     int l;
12     node() {l=0;memset(s,0,sizeof(s));}
13 };
14 node f[N+10];
15 
16 node operator*(node x,int y)//不可省掉构成运算符左右的整型
17 {
18     node z;
19     z.l=x.l;
20     for (int i=1;i<=z.l;i++)
21     {
22       z.s[i]+=x.s[i]*2;
23       if (z.s[i]>9) z.s[i+1]+=z.s[i]/10,z.s[i]%=10;
24     }
25     while (z.s[z.l+1]) z.l++;
26     return z;
27 }
28 node operator-(node x,int y)
29 {
30     node z=x;
31     int t=1;
32     z.s[t]--;
33     while (z.s[t]<0) z.s[t]+=10,z.s[++t]--;
34     while (!z.s[z.l]) z.l--;
35     return z;
36 }
37 node operator+(node x,int y)
38 {
39     node z=x;
40     int t=1;
41     z.s[t]++;
42     while (z.s[t]>9) z.s[t+1]+=z.s[t]/10,z.s[t++]%=10;
43     while (z.s[z.l+1]) z.l++;
44     return z;
45 }
46 void print(node x)
47 {
48     for (int i=x.l;i>=1;i--)
49       printf("%d",x.s[i]);
50     printf("\n");
51 }
52 int main()
53 {
54     freopen("a.in","r",stdin);
55     freopen("a.out","w",stdout);
56     f[1].l=1,f[1].s[1]=0;
57     for (int i=2;i<=N;i++)
58     {
59       if (i%2) f[i]=f[i-1]*2-1;
60       else f[i]=f[i-1]*2+1;
61     }
62     int n;
63     while(~scanf("%d",&n)) print(f[n]);
64     return 0;
65 }
View Code 高精度+重载运算符

P.S.重载运算符 不可省掉构成运算符左右的2个类型,例如:整型。

posted @ 2016-10-26 09:40  konjac蒟蒻  阅读(378)  评论(0编辑  收藏  举报