soj 1327. Pinary

题意:

定义pinary数,只由0,1组成,第一位数不是0,没有连续的1。

前若干pinary数:1,10,100,101,1000,1001,1010,.....

求第N个pinary数(N < 90,000,000)

思路:

对于K位的pinary数,显然第一位必然是1,对于接下来的两位,可能是01,可能是00,而01的情况数刚好是K-2位的pinary数,00的情况刚好是K-1位的pinary数,于是记F[k]为k位的pinary数的个数,则F[k] = F[k-1] + F[k-2]。进一步可以算出k位以内的pinary数的个数F[k] += F[k-1]。

这样,要求第N个pinary数,就可以依次确定顶位的1的位置,然后再减少N,再确定第二个1的位置,。。。依次进行下去。

得到F[] = 1,2,4,7,12。。。

例如,N = 12时,得到第一个大于等于N的F[i]是F[5],顾最高位第五位是1,此时N要减去(F[4]+1),得到N = 4,再进行下去,即可。

代码:

#include <cstdio>
#include <cstring>
#define B 40
int t, n, f[B], b, ans[B], c;
void calc()
{
	f[0] = 0; f[1] = 1;
	for (int i = 2; i < B; ++ i)
		f[i] = f[i-1] + f[i-2];
	for (int i = 2; i < B; ++ i)
		f[i] += f[i-1];
}
int main()
{
	calc();
	scanf("%d", &t);
	while (t --)
	{
		scanf("%d", &n);
		memset(ans, 0, sizeof(ans));
		for (b = 1; b < B; ++ b)
			if (n <= f[b]) break;
		while (n)
		{
			for (c = 1; c < B; ++ c)
				if (n <= f[c]) break;
			n -= (f[c-1]+1);
			ans[c] = 1;
		}
		for (c = b; c >= 1; -- c)
			printf("%d", ans[c]);
		printf("\n");
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值