问题描述
作为一个神秘的电脑高手,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. net core 使用 rabbitmq

    windows环境安装: https://www.cnblogs.com/ericli-ericli/p/5902270.html .NET Core 使用RabbitMQ https://www.c ...

  2. asp.net core 缓存和Session

    缓存 缓存在内存中 ASP.NET Core 使用 IMemoryCache内存中缓存是使用依赖关系注入从应用中引用的服务. 请在ConfigureServices中调用AddMemoryCache( ...

  3. 调整Windows操作系统下时间同步的频率

    今天发现时间不对,同步时间后看到Windows系统默认是一周才同步一次时间,频率太低了.查找了一下资料,找到了两种调整Win7时间同步频率的方法. 方法一:注册表法 这种方法是通过修改注册表中的键值来 ...

  4. Debug.Assert vs Exception Throwing(转载)

    来源 Q: I've read plenty of articles (and a couple of other similar questions that were posted on Stac ...

  5. CentOS安装CAS 5.3.4服务端

    1.安装jdk1.8 https://www.cnblogs.com/kgdxpr/p/6824093.html 2.安装tomcat8 3.安装maven https://www.cnblogs.c ...

  6. C++ ifstream ofstream

    原文出自[比特网],转载请保留原文链接:http://soft.chinabyte.com/database/460/11433960.sh [导读] ofstream是从内存到硬盘,ifstream ...

  7. request.user哪里来的?

    1.登录认证(auth认证登录后login后设置了session等信息包含用户的pk)      >>>>>               2.用户再次请求登录的时候,通过 ...

  8. TMS320DM642开发之Bug1-Memory map error:READ access by cpu to address 0x1b3f018(Device Config Space)which is not supported in simulator

    load程序到DM642开发板上之后,点击了run按钮出现了如下的错误: Memory map error:READ access by cpu to address 0x1b3f018(Device ...

  9. linux抓包工具Charles的配置安装

    1. 安装 (不赘述,方法很多,我使用yaourt charles安装) 2. 导出证书,crt格式保存备用 3. 浏览器导入证书 4. 浏览器设置代理

  10. Kafka 概念、单机搭建与使用

    目录 Kafka 概念.单机搭建与使用 基本概念介绍 Topic Producer Consumer Kafka单机配置,一个Broker 环境: 配置zookeeper 配置Kafka 使用Kafk ...