奶牛编号(Cowids) [NOIP模拟]
问题描述
作为一个神秘的电脑高手,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模拟]的更多相关文章
- 【NOIP2012模拟8.7】JZOJ2020年8月8日提高组T1 奶牛编号
[NOIP2012模拟8.7]JZOJ2020年8月8日提高组T1 奶牛编号 题目 作为一个神秘的电脑高手,Farmer John 用二进制数字标识他的奶牛. 然而,他有点迷信,标识奶牛用的二进制数字 ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 【noip模拟赛5】细菌 状压dp
[noip模拟赛5]细菌 描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...
- NOI.AC NOIP模拟赛 第五场 游记
NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...
- NOI.AC NOIP模拟赛 第三场 补记
NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...
- NOIP模拟题汇总(加厚版)
\(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...
- 【HHHOJ】NOIP模拟赛 玖 解题报告
点此进入比赛 得分: \(100+20+100=220\)(还不错) 排名: \(Rank\ 16\) \(Rating\):\(+20\) \(T1\):[HHHOJ263]「NOIP模拟赛 玖」三 ...
- 【HHHOJ】NOIP模拟赛 捌 解题报告
点此进入比赛 得分: \(30+30+70=130\)(弱爆了) 排名: \(Rank\ 22\) \(Rating\):\(-31\) \(T1\):[HHHOJ260]「NOIP模拟赛 捌」Dig ...
随机推荐
- net core 使用 rabbitmq
windows环境安装: https://www.cnblogs.com/ericli-ericli/p/5902270.html .NET Core 使用RabbitMQ https://www.c ...
- asp.net core 缓存和Session
缓存 缓存在内存中 ASP.NET Core 使用 IMemoryCache内存中缓存是使用依赖关系注入从应用中引用的服务. 请在ConfigureServices中调用AddMemoryCache( ...
- 调整Windows操作系统下时间同步的频率
今天发现时间不对,同步时间后看到Windows系统默认是一周才同步一次时间,频率太低了.查找了一下资料,找到了两种调整Win7时间同步频率的方法. 方法一:注册表法 这种方法是通过修改注册表中的键值来 ...
- Debug.Assert vs Exception Throwing(转载)
来源 Q: I've read plenty of articles (and a couple of other similar questions that were posted on Stac ...
- CentOS安装CAS 5.3.4服务端
1.安装jdk1.8 https://www.cnblogs.com/kgdxpr/p/6824093.html 2.安装tomcat8 3.安装maven https://www.cnblogs.c ...
- C++ ifstream ofstream
原文出自[比特网],转载请保留原文链接:http://soft.chinabyte.com/database/460/11433960.sh [导读] ofstream是从内存到硬盘,ifstream ...
- request.user哪里来的?
1.登录认证(auth认证登录后login后设置了session等信息包含用户的pk) >>>>> 2.用户再次请求登录的时候,通过 ...
- 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 ...
- linux抓包工具Charles的配置安装
1. 安装 (不赘述,方法很多,我使用yaourt charles安装) 2. 导出证书,crt格式保存备用 3. 浏览器导入证书 4. 浏览器设置代理
- Kafka 概念、单机搭建与使用
目录 Kafka 概念.单机搭建与使用 基本概念介绍 Topic Producer Consumer Kafka单机配置,一个Broker 环境: 配置zookeeper 配置Kafka 使用Kafk ...