soj 1327. Pinary
2013-01-08 14:13
197 查看
题意:
定义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,再进行下去,即可。
代码:
定义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"); } }
相关文章推荐
- Sicily 1327 Pinary (SOJ 1327) 【dp 动态规划】
- 1327. Pinary
- sicily 1327. Pinary
- sicily 1327. Pinary
- SOJ 3107 Select//最小割
- SOJ 4021 Cocircular Points
- soj 3316: Windy's Dates
- SOJ 2745 树状数组 TOJ 3505 树状数组
- SOJ 1689 算阶乘
- SOJ 3085: windy's cake V
- soj 1777. Mix order traversal
- soj 1197. Hotel
- soj 1278. Soldiers
- SOJ 2722: Treats for the Cows
- Sicily 1136 山海经 (SOJ 1136) 【Segment Tree 线段树】
- soj1209- 最短的距离(精度问题)
- SOJ 1310. Right-Heavy Tree
- SOJ-最大整数
- soj 1700 ping_简单dp
- UVA - 1350 Pinary (递推)