Kim Schrijvers
Consider an ordered set S of strings of N (1 <= N <= 31) bits. Bits, of course, are either 0 or 1.
This set of strings is interesting because it is ordered and contains all possible strings of length N that have L (1 <= L <= N) or fewer bits that are `1'.
Your task is to read a number I (1 <= I <= sizeof(S)) from the input and print the Ith element of the ordered set for N bits with no more than L bits that are `1'.
PROGRAM NAME: kimbits
INPUT FORMAT
A single line with three space separated integers: N, L, and I.
SAMPLE INPUT (file kimbits.in)
5 3 19
OUTPUT FORMAT
A single line containing the integer that represents the Ith element from the order set, as described.
SAMPLE OUTPUT (file kimbits.out)
10011
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; long long k; int dp[32][32]; int pos[32],t,pas,pass,passs; int main() { freopen("kimbits.in","r",stdin); freopen("kimbits.out","w",stdout); int i,j; scanf("%d%d%lld",&n,&m,&k); for(i=1;i<=31;++i) { dp[i][1]=i; dp[i][i]=1; } for(i=2;i<=31;++i) for(j=2;j<=i;++j) dp[i][j]=dp[i-1][j]+dp[i-1][j-1]; long long num=1; for(i=1;i<=n;++i) { num=1; for(j=1;j<=min(i,m);++j) num+=dp[i][j]; if(num==k) { for(j=1;j<=n-i;++j) printf("0"); for(j=1;j<=min(i,m);++j) printf("1"); for(j=1;j<=i-min(i,m);++j) printf("0"); printf("\n"); return 0; } if(num>k) { i--; num=1; for(j=1;j<=min(i,m);++j) num+=dp[i][j]; k-=num; break; } } pas=i; for(i=1;i<=pas;++i) { num=1; for(j=1;j<=min(i,m-1);++j) num+=dp[i][j]; if(num>=k) { i--; num=1; for(j=1;j<=min(i,m-1);++j) num+=dp[i][j]; k-=num; break; } } pass=i; if(pass!=0&&n>=30) { for(i=1;i<=pass;++i) { num=1; for(j=1;j<=min(i,m-2);++j) num+=dp[i][j]; if(num>=k) { i--; num=1; for(j=1;j<=min(i,m-2);++j) num+=dp[i][j]; k-=num; break; } } passs=i; } if(n>=30&&passs!=0) { for(i=1;i<=passs;++i) { num=1; for(j=1;j<=min(i,m-3);++j) num+=dp[i][j]; if(num>=k) { i--; num=1; for(j=1;j<=min(i,m-3);++j) num+=dp[i][j]; k-=num; break; } } } if(n>=30) { if(i==0) i=(1<<pas)+(1<<pass)+(1<<passs)-1,k=1; else i=(1<<pas)+(1<<pass)+(1<<passs)+(1<<i)-1; } else { if(i==0) i=(1<<pas)-1,k=1; else i=(1<<pas)+(1<<i)-1; } //i=(1<<(i+1))-1; int p=0; while(p<k) { i++; j=i; t=0; while(j>0) { t++; pos[t]=j%2; j/=2; } int num=0; for(j=1;j<=t;++j) if(pos[j]==1) num++; if(num<=m&&t<=n) p++; } for(i=1;i<=n-t;++i) printf("0"); for(i=t;i>=1;--i) printf("%d",pos[i]); printf("\n"); return 0; }
还有buffms大神的优美代码:
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; long long q[40][40]; int time1[40]; void add(int s){ int t=2; while(s!=1){ if(s%t==0){ time1[t]++; s/=t; }else t++; } return; } void shan(int s){ int t=2; while(s!=1){ if(s%t==0){ time1[t]--; s/=t; }else t++; } return; } long long c(int p,int q){ if(p<q)return 0; long long ans=1; memset(time1,0,sizeof(time1)); for(int i=1;i<=p;i++)add(i); for(int i=1;i<=q;i++)shan(i); for(int i=1;i<=(p-q);i++)shan(i); for(int i=1;i<=p;i++){ for(int j=1;j<=time1[i];j++){ ans*=i; } } return ans; } long long get(int pos,int len){ long long ans=0; for(int i=1;i<=len;i++){ ans+=q[pos-1][i]; } return ans+1; } void wait(){ for(int i=1;i<=32;i++){ for(int j=i;j>=0;j--){ q[i][j]=c(i,j); } } } int dp[1000]; int main(){ freopen("kimbits.in","r",stdin); freopen("kimbits.out","w",stdout); int n,l; long long k; wait(); scanf("%d%d",&n,&l); cin>>k; int last=l; while(k!=0){ for(int i=1;i<=n+1;i++){ long long getans=get(i,last)+1; if(k<getans){ dp[i-1]=1; k-=get(i-1,last); last--; break; }else if(k==getans){ dp[i]=1; k-=getans; break; } } } for(int i=n;i>=1;i--) printf("%d",dp[i]); printf("\n"); }
全是0.000s哦!!!!!
此题还是一道很不错的题目,推荐自己好好想一下。