1041:Computer Transformation

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
 

分析:


由上图可以得知:数字num对应的0的对数为s[num] = s[num - 1] + 2 * s[num - 2]

虽然step5中,s[num-1]与‘s[num-1]位刚刚相反 ,但是,step4以后的所有序列中间位置均有00对出现,弥补了‘s[num-1]相对于s[num-1]缺少的那对00,故存在:s[num] = s[num - 1] + 2 * s[num - 2]

解答:

首先根据规律想到的一种错误解法,代码如下:

#include <iostream>
#include <time.h>
#include <iomanip>
using namespace std;

long long int sum(int n)
{
	long long int temp;
	if(n == 1)
		temp = 0;
	else 
		if(n%2)
			temp = 2 * sum(n - 1) - 1;
		else
			temp = 2 * sum(n - 1) + 1;
	return temp;
}

int main()
{
	int n;
	while(cin >> n){
		clock_t start = clock();
		if (n < 1 || n > 1000)
			exit(-1);
		cout << sum(n) << endl;
		double finish = clock();
		cout << "complete time: " << setiosflags(ios::fixed) << setprecision(6) << finish - start << endl;
	}

	return 0;
}

运行此程序当输入数据较大时候就会产生负数,这就涉及到了大数据存储问题,我们可以通过一个数组来存放一个任意大的数据,通过数组的引入,我们得到以下一种正确的代码:

#include <iostream>
#include <string>
using namespace std;

//输入数据num的最大取值
#define NUM_MAX 1000
//大数据可能拥有的位数
#define N 350
//定义一个全局的二维数组
int s[1000][351];

int main()
{
	//num代表要计算的步骤数,carry代表进位
	int num, carry = 0;
	//将所有num从1到1000产生的数据全部计算出来,并存储在一个二维数组s[num][1...i]中
	s[0][0] = 0;
	s[1][0] = 0;
	s[2][0] = 1;
	s[3][0] = 1;

	//将数据的各个位(个位、十位、、、)存入到数组中每个位置s[0][0]、s[1][0](s[1][1]=1)
	for(int i = 4; i <= NUM_MAX; ++i)
	{
		for(int j = 0; j <= N; ++j)
		{
			s[i][j] = s[i-1][j] + 2*s[i-2][j] + carry;
			carry = s[i][j] / 10;
			s[i][j] %= 10;
		}
	}

	//输入一个数据num
	while(cin >> num)
	{
		if(num == 1)
		{
			cout << 0 << endl;
			continue;
		}

		int i;
		//找到num产生的数据的最高位
		for(i = N; i > 0; --i)
			if(s[num][i] != 0)
				break;
		//从由num产生的数据的最高位进行输出
		for(int j=i; j >= 0; --j)
			cout << s[num][j];
		cout << endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值