[USACO12FEB]牛的IDCow IDs

题目描述

Being a secret computer geek, Farmer John labels all of his cows with binary numbers. However, he is a bit superstitious, and only labels cows with binary numbers that have exactly K "1" bits (1 <= K <= 10). The leading bit of each label is always a "1" bit, of course. FJ assigns labels in increasing numeric order, starting from the smallest possible valid label -- a K-bit number consisting of all "1" bits. Unfortunately, he loses track of his labeling and needs your help: please determine the Nth label he should assign (1 <= N <= 10^7).

FJ给他的奶牛用二进制进行编号,每个编号恰好包含K 个"1" (1 <= K <= 10),且必须是1开头。FJ按升序编号,第一个编号是由K个"1"组成。

请问第N(1 <= N <= 10^7)个编号是什么。

输入输出格式

输入格式:

 

  • Line 1: Two space-separated integers, N and K.

 

输出格式:

 

输入输出样例

输入样例#1:
7 3 
输出样例#1:
10110 
我们先将这个串用足够大小保存,足够大的话我们可以添加前导0,到最后从第一个非0位输出即可,也就是说我们要找到一个m,使得C(m,k) >= n,可以二分求m
这题最坑的是为了防止溢出longlong,所以要将k分情况制定二分右界

如果做到第i位,还要填j个1,那么这一位填0的方案数就是C(i-1,j),即还剩i-1位可以填j个1的方案数。

如果这个数小于n,那么这一位填1,并且n要减去这个数,否则这一位填0。

myys

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 ll n;
 8 int k,cnt,m,ans[1001];
 9 ll C(int x,int y)
10 {int i;
11   if (x>y) return 0;
12   ll s=1;
13   for (i=y;i>y-x;i--)
14     s*=i;
15   for (i=x;i>=2;i--)
16     s/=i;
17   return s;
18 }
19 int main()
20 {int i;
21   cin>>n>>k;
22   if (k==1)
23     {
24       cout<<1;
25       for (i=n-1;i>=1;i--)
26     {
27       printf("0");
28     }
29       return 0;
30     }
31   int l=1,r;
32   if (k>=10)
33   r=600;
34   else if (k>=7)
35     r=1000;
36   else r=8000;
37   while (l<=r)
38     {
39       int mid=(l+r)/2;
40       if (C(k,mid)>=n) m=mid,r=mid-1;
41       else l=mid+1;
42     }
43   cnt=0;
44   for (i=m;i>=1;i--)
45     {
46       ll p=C(k,i-1);
47       if (p<n) 
48     {
49       k--;
50       ans[i]=1;
51       n-=p;
52       if (cnt==0)
53         {
54           cnt=i;
55         }
56     }
57       if (k==0||n==0)
58     {
59       break;
60     }
61     }
62   for (i=cnt;i>=1;i--)
63     printf("%d",ans[i]);
64 }

 

posted @ 2017-10-12 16:53  Z-Y-Y-S  阅读(546)  评论(0编辑  收藏  举报