HDOJ-1041 Computer Transformation(找规律+大数运算)

http://acm.hdu.edu.cn/showproblem.php?pid=1041

有一个初始只有一个1的串 每次都按①0 -> 10;②1 -> 01;这两条规则进行替换

形如:n = 1  1

   n = 2  01

   n = 3  1001

   ...

求经过n步替换之后 串中只含复数个0的连续子串(不难发现,这种子串只能是‘00’)的出现次数

 

因为0<n<=1000的限制 在最坏情况下(n==1000)串的长度将达到2^1000位 排除了直接模拟上述替换过程的可能

列出前几项的替换结果:

n = 0                       1  ‘00’=0  ‘01’=0
n = 1                       01  ‘00’=0  ‘01’=1
n = 2                     1001  ‘00’=1  ‘01’=0
n = 3                   01101001  ‘00’=1  ‘01’=2
n = 4              1001011001101001  ‘00’=3  ‘01’=2
n = 5   01101001100101101001011001101001  ‘00’=5  ‘01’=6

在上面的数据 不仅给出结果串 还统计出了串中‘00’对和‘01’对的个数【注:‘01’的个数是取出全部的‘00’对后才统计】

从n = 3开始 观察可以发现 01 -> 1001    即每个00对(1001)都是由01对转化而来

而每个00对(1001)又将产生一个 00对 和 两个 01对(见n=2->3)

由上述可得 n步时00对的个数 = n-1步的00对的个数 + n-1的01对的个数(即n-2步的00对的个数 * 2)

所以可以推得 f(n) = f(n - 1) + f(n - 2) * 2

如果细心的话,可以发现,当n大到一定程度时,由于上面给出的公式有着与斐波拉契数列相似的递增效应, 最终结果的数值会非常大大大大大,用__int64都远远无法满足

所以采用字符数组来模拟大数加法运算

# include <stdio.h>
# include <string.h>
# define MAX 1001
# define LEN 1001

char Number[MAX][LEN];

void BigNumPlus()
{
	for(int i = 3; i < MAX; i++)
	{
		memset(Number[i], '0', LEN);//初始化

		for(int j = 0; j < LEN; j++)//模拟公式
		{
			Number[i][j] += (Number[i - 1][j] - '0') + (Number[i - 2][j] - '0') + (Number[i - 2][j] - '0');
		}

		for(int j = 0; j < LEN; j++)//处理进位
		{
			if(Number[i][j] > '9')
			{
				Number[i][j + 1] += (Number[i][j] - '0') / 10;
				Number[i][j] = (Number[i][j] - '0') % 10 + '0';
			}
		}
	}
}

int main()
{
	//初始值
	memset(Number[1], '0', LEN);
	memset(Number[2], '0', LEN);
	Number[1][0] = '0';
	Number[2][0] = '1';

	BigNumPlus();

	int n;
	while(scanf("%d",&n) != EOF)
	{
		if(n == 1)//特殊处理
		{
			printf("0\n");
			continue;

		}
		for(int i = LEN - 1; i >= 0; i--)
		{
			if(Number[n][i] != '0')//格式输出
			{
				while(i >= 0) printf("%c",Number[n][i--]);
				printf("\n");
				break;
			}
		}
	}

	return 0;
}

  

转载于:https://www.cnblogs.com/linjiaman/p/4297191.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值