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

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

输出
如题,第 N 个标识数字

输入输出样例
7 3

10110

思路

我思路真的很复杂(因为我太蒻了),不过有一些是很有价值的思想

就以样例做比方,其前几个排列是:

  111
1011
1101
1110
10011
10101
10110
11001
11100 ......

除了第一个,我们发现,把相同长度的分为一组,第i组内的大小为C(2+i,i)  [扩展到整道题就是C( k-1+i , i )]

我们就可以通过组合数的方式快速找到第n个数属于第几组

而在某一组内如何快速找到它的位置呢?

我们就数据中长度为5的那一组分析,抛开开头的1,0的位置依次为

1 2  1 3  1 4  2 3  2 4  3 4

也就是求C(2+i,i)中字典序大小的第m项 (设第n个数在这一组排第m项)

显然一项一项枚举是会T掉的,那我们可以怎样判断出某一位是几?

我们设总共有L个数字可选,D个位置可填,该位填的数字为i,现在填的第step位  (例子中L=4 D=2)

那么step位填i后,后面可填的方案数为C(L-i,D-step)

如果C>=m,说明这一位就填i,下一位就从i+1开始搜

否则这一位肯定不填i,m-=C后,继续判断该位是否填i+1

这样,我们就可以以近乎O(L)地判断出来第m项了。

Code

 #include<set>
#include<map>
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf (1<<30)
#define ll long long
#define RG register int
#define rep(i,a,b) for(RG i=a;i<=b;i++)
#define per(i,a,b) for(RG i=a;i>=b;i--)
#define maxn 1000005
#define lim 1000002
using namespace std;
ll N,k,cnt,dep,numlim;
int pri[maxn],p[maxn],vis[maxn];
ll rec[][];
inline ll read()
{
ll x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void pre()
{
rep(i,,lim)
{
if(!pri[i]) p[++cnt]=i;
for(RG j=;j<=cnt&&i*p[j]<=lim;j++)
{
pri[i*p[j]]=;if(!(i%p[j])) break;
}
}
} ll work(ll x,ll p)
{
ll res=;
while(x) res+=x/p,x/=p;
return res;
} ll QP(ll a,ll mi)
{
ll ans=;
while(mi)
{
if(mi&) ans*=a;
a*=a;
mi>>=;
}
return ans;
} ll cnm(ll n,ll m)
{
ll ans=;
for(RG i=;p[i]<=n;i++)
{
ll _1=work(n,p[i]);
ll _2=work(m,p[i]);
ll _3=work(n-m,p[i]);
ans*=QP(p[i],_1-_2-_3);
}
return ans;
} void pt()
{
cout<<;
rep(i,,numlim)
{
printf("%d",!vis[i]);
}
exit();
} void dfs(int step,int st)
{
if(step>dep)
{
pt();
return;
}
for(int i=st;i<=numlim;i++)
{
int nn=numlim-i,mm=dep-step,cc;
if(rec[nn][mm]) cc=rec[nn][mm];
else rec[nn][mm]=cc=cnm(nn,mm);
if(cc<N){N-=cc;continue;}
vis[i]=;
dfs(step+,i+);
vis[i]=;
}
} void work()
{
if(N==){rep(i,,k)cout<<;return;}--N;
for(register ll i=k,j=;;++i,++j)
{
ll C=cnm(i,j);rec[i][j]=C;
if(C>=N) {numlim=i,dep=j;break;}
N-=C;
}
dfs(,);
} void work1()
{
cout<<;rep(i,,N) printf(""); exit();
} int main()
{
N=read(),k=read();
if(k==) work1();
pre();
work();
return ;
}

奶牛编号(Cowids) [NOIP模拟]的更多相关文章

  1. 【NOIP2012模拟8.7】JZOJ2020年8月8日提高组T1 奶牛编号

    [NOIP2012模拟8.7]JZOJ2020年8月8日提高组T1 奶牛编号 题目 作为一个神秘的电脑高手,Farmer John 用二进制数字标识他的奶牛. 然而,他有点迷信,标识奶牛用的二进制数字 ...

  2. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 【noip模拟赛5】细菌 状压dp

    [noip模拟赛5]细菌   描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...

  5. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  6. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  7. NOIP模拟题汇总(加厚版)

    \(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...

  8. 【HHHOJ】NOIP模拟赛 玖 解题报告

    点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...

  9. 【HHHOJ】NOIP模拟赛 捌 解题报告

    点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...

随机推荐

  1. 目标检测算法之R-CNN算法详解

    R-CNN全称为Region-CNN,它可以说是第一个成功地将深度学习应用到目标检测上的算法.后面提到的Fast R-CNN.Faster R-CNN全部都是建立在R-CNN的基础上的. 传统目标检测 ...

  2. rsa证书ssh登陆服务器

    好久不用,又生疏了. 今晚实操了一下,作一个记录. 使用rsa的密钥对登陆linux服务器,主要是为了安全. 这种证书级别的登陆,比最复杂的root用户名和帐号的安全性都要高一个等级. 至少服务器不会 ...

  3. java.net.ConnectException: Call From slaver1/192.168.19.128 to slaver1:8020 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org

    1:练习spark的时候,操作大概如我读取hdfs上面的文件,然后spark懒加载以后,我读取详细信息出现如下所示的错误,错误虽然不大,我感觉有必要记录一下,因为错误的起因是对命令的不熟悉造成的,错误 ...

  4. 学习笔记: 反射应用、原理,完成扩展,emit动态代码

    using Ruanmou.DB.Interface; using Ruanmou.DB.MySql; using Ruanmou.DB.SqlServer; using Ruanmou.Model; ...

  5. 牛客网round1

    题解: 1. 二分答案之后判断 把式子移项使得x,y不关联 #include <bits/stdc++.h> using namespace std; #define rint regis ...

  6. 一起学Hadoop——Hadoop的前世今生

    Hadoop是什么? Hadoop是一个处理海量数据的开源框架.2002年Nutch项目面世,这是一个爬取网页工具和搜索引擎系统,和其他众多的工具一样,都遇到了在处理海量数据时效率低下,无法存储爬取网 ...

  7. 【Arduino】开发入门【十】Arduino蓝牙模块与Android实现通信

    [Arduino]开发入门[十]蓝牙模块 首先show一下新入手的蓝牙模块 蓝牙参数特点 1.蓝牙核心模块使用HC-06从模块,引出接口包括VCC,GND,TXD,RXD,预留LED状态输出脚,单片机 ...

  8. python_异常处理_断言

    一.Python标准异常 常用异常 Exception 常规错误的基类 AttributeError 试图访问一个对象没有的属性 IOError 输入/ 输出异常,基本上是无法打开文件 ImportE ...

  9. img没有src属性时自动出现边框

    当img没有接收到src属性的时候会自动出现边框,border:0/none都不管用的情况下 解决方法 一行css 可以解决 img[src=""],img:not([src]){ ...

  10. Python中元类

    元类(metaclass) 简单地说,元类就是一个能创建类的类,而类class 是由type创建的,class可以创建对象 type与object的关系详见:python中type和object 1. ...