``Pinary" number is a positive number using only two digits ``0" and ``1" with usual rule that it must not begin with a 0, and the additional rule that two successive digits must not be both ``1". This means that the factor ``11" is forbidden in the string. So the allowed Pinary writings are 1, 10, 100, 101, 1000, 1001,..., 100010101010100010001 . For example, ``100101000" is a Pinary number, but neither ``0010101" nor ``10110001" are Pinary numbers.
Each Pinary number represents a positive integer in the order they appear (using length order, lexicographic order), that is, 1 is mapped to 1, 10 is mapped to 2. And 100, 101 and 1000 are mapped to 3, 4 and 5, respectively. You are to write a program to generate Pinary number representations for integers given.
Input
Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case starts with a line containing a postive integer 2 < K < 90, 000, 000 .
Output
Your program is to write to standard output. Print exactly one line for each test case. For each test case, print the Pinary number representation for input integer. The following shows sample input and output for three test cases.
Sample Input
3 7 2000 22
Sample Output
1010 1001000001001000 1000001
解题报告: 求第k个没有前导0和连续1的01串。
首先可以递推一下。用dp[i][j]表示长度为i,第一个数为j的串的数量。那么,dp[i][0]=dp[i-1][0]+dp[i-1][1], dp[i][1]=dp[i-1][0]。
可以知道dp[i][1]满足斐波那契数列。对dp[i][1]预处理求和,得到sum数组。sum[i]就表示i位的符合条件的二进制串的数量。
对输入的n进行二分查找,则那一位必定是首位1,而且表示的数的sum[i-1]+1。减去该数,遍历一遍。发现能减去时则减去,并且打印1,否则打印0。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 90000000;
int num[10000];
int sum[10000];
int top;
void init()
{
num[2]=num[1]=1;
sum[1]=1;sum[2]=2;
for(int i=3;sum[i-1]<=maxn;i++)
{
num[i]=num[i-1]+num[i-2];
sum[i]=sum[i-1]+num[i];
if(sum[i]>=maxn)
{
top=i+1;
break;
}
}
}
void work()
{
int n;
scanf("%d",&n);
int pos = lower_bound(sum+1,sum+top,n)-sum;
for(int i=pos;i;i--)
{
if(n>sum[i-1])
printf("1"),n-=sum[i-1]+1;
else
printf("0");
}
puts("");
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
work();
}