#P2984. USACO(38)数位2:二进制编号来源[Cow Queueing, 2003 Dec]【SP1182】
USACO(38)数位2:二进制编号来源[Cow Queueing, 2003 Dec]【SP1182】
Description
测试数据的A和B为2进制
100
1111
51001
Hint
by hansang:#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=45;
char s1[N], s2[N]; LL d[N], c[N][N], ans[N];
LL dfs(LL x, LL t, LL k){
if(t==0 && k==0) return 1;
if(x<0 || t==0 || k<0) return 0;
if(x&d[t-1]) return c[t-1][k]+dfs(x, t-1, k-1);
else return dfs(x, t-1, k);
}
int main(){
d[0]=1; for(int i=1; i<=40; i++) d[i]=d[i-1]*2;
memset(c, 0, sizeof(c)); c[0][0]=1;
for(int i=1; i<=40; i++){
c[i][0]=1;
for(int j=1; j<=i; j++) c[i][j]=c[i-1][j]+c[i-1][j-1];
}
scanf("%s%s", s1+1, s2+1);
LL K, A=0, B=0; scanf("%lld", &K);
int len1=strlen(s1+1), len2=strlen(s2+1);
for(int i=len1; i>=1; i--){
A+=(s1[len1-i+1]-'0')*d[i-1];
}
for(int i=len2; i>=1; i--){
B+=(s2[len2-i+1]-'0')*d[i-1];
}
if(A>B) swap(A, B);
LL sum=0, t=0, k;
for(int i=0; i<32; i++){
LL x=dfs(B, 32, i)-dfs(A-1, 32, i);
if(sum+x<K) sum+=x, t=i;
else {k=K-sum; break;}
}
t++;
LL l=A, r=B, x=dfs(A-1, 32, t), res=0;
while(l<=r){
LL mid=(l+r)/2;
if(dfs(mid, 32, t)-x>=k) r=mid-1, res=mid;
else l=mid+1;
}
int len=0;
while(res>0) ans[++len]=res%2, res/=2;
for(int i=len; i>=1; i--) printf("%d", ans[i]);
printf("\n");
return 0;
}
</p>