码迷,mamicode.com
首页 > 其他好文 > 详细

奶牛编号 cowids

时间:2019-06-28 22:48:13      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:+=   第一个   inpu   i++   相同   signed   putchar   char   bit   

奶牛编号

Description

作为一个神秘的电脑高手,Farmer John 用二进制数字标识他的奶牛。然而,他有点迷信,标识奶牛用的二进制数
字,必须只含有K位"1"(1 <= K <= 10)。 当然,每个标识数字的首位必须为"1"。FJ按递增的顺序,安排标识数字
,开始是最小可行的标识数字(由"1"组成的一个K位数)。不幸的是,他没有记录下标识数字。请帮他计算,第N
个标识数字(1 <= N <= 10^7)。

Input

第1行:空格隔开的两个整数,N和K。

Output

如题,第N个标识数字

Sample Input

7 3 

Sample Output

10110

Solution

在len长区间中取k个数为1,第一位为1,方案数为C(len-1,k-1)

\(f(i,j)=\sum\limits_{x=1}^{i}C(x,j)\)

对于题目中的n和k,求出i,使得$f(i,k-1)\le n<f(i+1,k-1) $

则有字符串的长度len=i+1

这样我们就得到了第一个‘1‘的位置了

此时令:\(n=n-f(i,k-1)\ ,\ k=k-1\)

接着以相同方式求出剩下的‘1‘的位置

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
    int f=1,re=0;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())re=re*10+ch-'0';
    return f*re;
}
int C(int n,int m){
    if(!m)return 1;
    int re=1;
    for(int i=n;i>=n-m+1;i--)re*=i;
    for(int i=1;i<=m;i++)re/=i;
    return re;
}
int n,k;
signed main(){
//  freopen("cowids.in","r",stdin);
//  freopen("cowids.out","w",stdout);
    n=read(),k=read();
    int len,tot,lst,tmp;
    len=k-1,tot=0,tmp=C(len,k-1);
    while(tot+tmp<n){
        tot+=tmp;
        tmp=C(++len,k-1);
    }
    lst=len,n-=tot;
    putchar('1');
    for(k--;k;k--){
        len=k-1,tot=0,tmp=C(len,k-1);
        while(tot+tmp<n){
            tot+=tmp;
            tmp=C(++len,k-1);
        }
        for(int i=1;i<=lst-len-1;i++)putchar('0');
        lst=len,n-=tot;
        putchar('1');
    }
    for(int i=1;i<=len;i++)putchar('0');
    return 0;
}
/*
7 3

*/

奶牛编号 cowids

标签:+=   第一个   inpu   i++   相同   signed   putchar   char   bit   

原文地址:https://www.cnblogs.com/nlKOG/p/11104817.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!