1081. Binary Lexicographic Sequence
http://acm.timus.ru/problem.aspx?space=1&num=1081
Time limit: 0.5 second
Memory limit: 64 MB
Consider all the sequences with length (0 < N < 44), containing only the elements 0 and 1, and no two ones are adjacent (110 is not a valid sequence of length 3, 0101 is a valid sequence of length 4). Write a program which finds the sequence, which is on K-th place (0 < K < 109) in the lexicographically sorted in ascending order collection of the described sequences.
Input
The first line of input contains two positive integers N and K.
Output
Write the found sequence or −1 if the number K is larger then the number of valid sequences.
Sample
input | output |
---|---|
3 1 | 000 |
先来枚举几个情况
N为1时:
按字典序就有字符串:
0
1
N为2时:
按字典序就有字符串:
00
01
10
N为3时:
按字典序就有字符串:
000
001
010
101
N为4时:
按字典序就有字符串:
0000
0001
0010
0100
0101
1000
1001
1010
令p(N)为长度为N的字符串数,则前p(N-1)个即为N-1长度的字符串序列中的每一个字符串前加上一个0,而后p(N)-p(N-1)即为N-2长度的字符串序列中的每一个字符串前加上10。因此得到一个k后就可以通过不断向前回溯得到字符串
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
int rule[45];
void init()
{
rule[1]=2;rule[2]=3;
for(int i=3;i<=44;i++)
{
rule[i]=rule[i-1]+rule[i-2];
}
}
int arr[45];
int main()
{
init();int n,k;
while(cin>>n>>k)
{
memset(arr,0,sizeof(arr));
if(k>rule[n])
{
cout<<"-1"<<endl;
continue;
}
int up=lower_bound(rule,rule+45,k)-rule;
int temp=k;
//cout<<up<<endl;
while(up>2)
{
arr[up]=1;
temp=temp-rule[up-1];
up=lower_bound(rule,rule+45,temp)-rule;
//cout<<temp<<endl;
}
if(up<=2)
{
if(temp==2) arr[1]=1;
if(temp==3) arr[2]=1;
}
for(int i=n;i>=1;--i)
{
printf("%d",arr[i]);
}
printf("\n");
}
return 0;
}