杭电1041

Computer Transformation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6895    Accepted Submission(s): 2499


Problem Description
A sequence consisting of one digit, the number 1 is initially written into a computer. At each successive time step, the computer simultaneously tranforms each digit 0 into the sequence 1 0 and each digit 1 into the sequence 0 1. So, after the first time step, the sequence 0 1 is obtained; after the second, the sequence 1 0 0 1, after the third, the sequence 0 1 1 0 1 0 0 1 and so on.

How many pairs of consequitive zeroes will appear in the sequence after n steps?
 

Input
Every input line contains one natural number n (0 < n ≤1000).
 

Output
For each input n print the number of consecutive zeroes pairs that will appear in the sequence after n steps.
 

Sample Input
   
   
2 3
 

Sample Output
   
   
1 1

题意:电脑的内存首先是初始化为1.经过一段时间,变成0 和1。接着分别0变为 10,1又变为01。意思就是(1->0 1)(0->1 0)问经过n步。出现相邻的两个零的个数。

分析:

 此题,很明显就是找规律,不可能去模拟。多画几个,就大致可推出方程了。

 (1,0)  ,(2,1),(3,1),(4,3),(5,5),(6,11)………(说明:第一个数代表步数,第二个出现两个零的个数)

规律:

       0   1                           0
       1   01                         0
       2   1001                         1
       3   01101001                      1
       4   1001011001101001                 3
       5   01101001100101101001011001101001      5

其递归方程为: f(n)=f(n-1)+2*f(n-2). 

从第四项开始:f(n)=2^k+f(n-2)(n=4,5,6....)(k=1,2,3,4....)

            step4 :    3  =2^1+1

            step5 :    5  =2^2+1

            step6:     11=2^3+3

写的过程中发现每步的数字增加了2^n的数据,数据非常大,考虑到应该是道大数的题目,最后在大神的指导下,找到了个很巧妙的方法,开了两个数组,一个用来存取连续0的个数,一个用来递增过渡相加。

代码:

#include<stdio.h>
#define MAX 1000
int n[MAX][400]={{0},{0},{1},{1}}; //前四项初始化
int b[MAX]={1};


void maxn(){
int i,j,k,z;
for(i=4;i<=MAX;i++){
for(j=0,k=0,z=0;j<400;j++){
b[j]=2*b[j]+k;          //数组b存取2^n,降位存取。
k=b[j]/10;         
b[j]=b[j]%10;


n[i][j]=b[j]+n[i-2][j]+z;//数组n存取连续字段0的个数,降位存取。
z=n[i][j]/10;
n[i][j]=n[i][j]%10;
}
}
}


int main(){
int i,N,flag;
maxn();
while(~scanf("%d",&N)){
flag=0;
if(N==1)
printf("0");
else if(N==2 ||N==3)
printf("1");
else
for(i=399;i>=0;i--){
if(n[N][i] || flag){
printf("%d",n[N][i]);
flag=1;
}
}
printf("\n");
}
return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值