【题解】UVA1647[ACM/ICPC SEERC 2005].Computer Transformations 递推

题目链接
参考了大佬博客思路摘抄如下:
数学题。我们观察变化。
00 -> 1010 出现 10、01
01 -> 1001 出现 10、00、01
10 -> 0110 出现 01、11、10
11 -> 0101 出现 01、10
只有01下一步会生成00,但是00、01、10、11都会生成01,每一个1都会生成01,而00也可以生成01,
由此分成两种情况计算;设O(n)是变化n步后1的个数,Z(n)是变化n步后生成的00的个数,有结论:
Z(n)= Z(n-2)+ O(n-2),O(n)= 2^(n-1){无论0、1都会生成0与1,所以是位数的一半}

#include<cstdio>
#include<cstring>
const int N=1e3+10;
int a[N][150],b[N][150];
void Init()
{
    a[0][0]=a[1][0]=1;
    memset(b,0,sizeof(b));
    for(int i=2;i<=1000;i++)
    for(int j=0;j<=140;j++)
    {
        a[i][j]+=a[i-1][j]*2;//n步后长度为2^n,一个数为2^(n-1)
        b[i][j]+=b[i-2][j]+a[i-2][j];
        a[i][j+1]+=a[i][j]/10000;//每位存四位数
        a[i][j]%=10000;
        b[i][j+1]+=b[i][j]/10000;
        b[i][j]%=10000; 
    }
}
int main()
{
    Init();
    int n;
    while(~scanf("%d",&n))
    {
        int i;
        for(i=140;i&&!b[n][i];i--);
        printf("%d",b[n][i--]);
        for(;i>=0;i--)printf("%04d",b[n][i]);
        puts("");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值