uva1350 Pinary(递推)

来源:互联网 发布:linux 打开本地目录 编辑:程序博客网 时间:2024/06/04 19:24

题意:求第k大的无前导0和连续1的二进制数
解法:递推+二分查找
1.得到st[i]:第i位是1的前i位数列个数,sum[i]:前i为数列个数和
st[i]=st[i-2]+st[i-3]+…+st[0]
该递推式等价于st[i]=st[i-1]+st[i-2]
2.二分查找sum序列。并减去由于l位为1,l-1位不能为1的中间略去的数(sum[l-1]+1)

# include<iostream># include<cstdio># include<algorithm># include<queue># include<stack># include<math.h># include<cstring># define INF 0x3f3f3f3f# define ll long longusing namespace std;const int maxn = 1000+10;const int maxm = 90000000+10;int t,n;int tmp;int st[maxn],sum[maxn];//st[i]:第i位是1的前i位数列个数;int ans[maxn];int maxx;int main(){    st[1]=st[2]=1;    sum[1]=1,sum[2]=2;    for(int i=3;i<maxn;i++){        st[i]=st[i-1]+st[i-2];        sum[i]=st[i]+sum[i-1];        if(sum[i]>maxm) {tmp=i; break; }    }    //freopen("a.txt","r",stdin);    scanf("%d",&t);    while(t--){        scanf("%d",&n);        maxx=0;        memset(ans,0,sizeof(ans));        while(n){            int l=lower_bound(sum+1,sum+tmp+1,n)-sum;            maxx=max(maxx,l);            ans[l]=1;            n-=(sum[l-1]+1);        }        for(int i=maxx;i>=1;i--){            printf("%d",ans[i]);        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击