uva1350 - Pinary 第N个满足条件的二进制数

``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
 

  num[i]表示i位数满足条件的有多少个,sum[i]表示小于等于i位数满足条件的有多少个。

  num[i]=num[i-1]+num[i-2]

  sum[i]=sum[i-1]+sum[i-2]+1

  统计的时候i从大到小循环,如果N>sum[i],说明i位已经满足不了了,那么第i+1位肯定为1,N要减去sum[i]+1,因为第i+1位取0的时候后面有sum[i]种,第i+1位取1的时候后面都取0也符合,而0000这种串不包含在sum里。那这样会不会出现第i位取1,第i-1位又取1的不符合题意的情况呢?是不会的,因为若N>sum[i]并且N-sum[i]-1>sum[i-1],就是N>sum[i]+sum[i-1]+1,因为sum[i+1]=sum[i]+sum[i-1]+1,说明N>sum[i+1],那么就会在i+1位取1而不会在i和i-1取两个连续的1了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<cmath>
#define INF 0x3f3f3f3f
#define MAXN 50
#define MAXM 20010
#define MAXNODE 4*MAXN
#define MOD 1000000000
#define eps 1e-9
using namespace std;
int T,N,ans[MAXN];
long long num[MAXN],sum[MAXN];
void init(){
    memset(num,0,sizeof(num));
    memset(sum,0,sizeof(sum));
    num[1]=num[2]=sum[1]=1;
    sum[2]=2;
    for(int i=3;i<MAXN;i++){
        num[i]=num[i-1]+num[i-2];
        sum[i]=sum[i-1]+num[i];
    }
}
int main(){
    //freopen("in.txt", "r", stdin);
    init();
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        memset(ans,0,sizeof(ans));
        for(int i=MAXN-1;i>=0;i--){
            if(N>sum[i]){
                ans[i+1]=1;
                N-=sum[i]+1;
            }
        }
        int first=1;
        for(int i=MAXN-1;i>0;i--){
            if(ans[i]){
                printf("1");
                first=0;
            }
            else if(!first) printf("0");
        }
        puts("");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值