E - ( ;´Д`) URAL - 1081 Binary Lexicographic Sequence 递归

E - ( ;´Д`)

 URAL - 1081  

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 < 10 9) 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.

Example

input output
3 1
000

题意:输出字典序第k大长度为n的01串(1不能相邻),没有就输出-1

写出前几个可以发现,当最高位的1在第i位时,就相当于在第i位上填1,i-1位是0,再把最高位的1是第0(没有1)位~第i-2位的方案放在i-2~1位上,即最高位的1在第i位时f[i]=sum(f[0]~f[i-2])种方案,最后一种方案排在sum(f[0]~f[i]),到这里就可以看出怎么递归了。具体看代码。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

typedef long long LL;
using namespace std;
const int maxn=44;
const int mod=10056;
LL f[maxn];//最高位的1在第i位时的方案数
LL sf[maxn];//最高位的1在第i位时的最大一个方案的排名
int ans[maxn];//输出
void init()
{

    f[0]=f[1]=f[2]=1;
    sf[0]=1;
    sf[1]=2;
    sf[2]=3;
    LL sum=2;
    for(int i=3;i<maxn;i++)
    {
        f[i]=sum;
        sum+=f[i-1];
        sf[i-1]=sum;
    }
    sf[maxn-1]=sum+f[maxn-1];
}
void solve(int k)//每次递归写上第k名最高位的1
{
    int x;
    for(int i=0;i<maxn;i++)//找到第k名最高位的1在第几位
    {
        if(sf[i]>=k)
        {
            x=i;
            break;
        }
    }
    //printf("**%d %d %d\n",x,k,sf[x]);
    if(x==0||x==1)
    {
        ans[43]=x;
        return;
    }
    ans[43-x+1]=1;
    solve(k%sf[x-1]);//确定最高位的1在x位,后面的数字会从第1名开始重复到最高位的1在x-2位的最后一个方案为止(包括x-2),既f[x]的第一个方案为1000...0,第二个为x000...1

}
int main()
{

    int n,k;
    init();
    while(~scanf("%d%d",&n,&k))
    {
        int x;
        for(int i=0;i<maxn;i++)
        {
            if(sf[i]>=k)
            {
                x=i;
                break;
            }
        }
        if(x>n){printf("-1\n");continue;}
        
        memset(ans,0,sizeof(ans));
        solve(k);
        for(int i=44-n;i<44;i++)
        {
            printf("%d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

 

 

posted on 2018-08-01 10:49  一零七  阅读(117)  评论(0编辑  收藏  举报

导航