洛谷-3048 [USACO12FEB]牛的IDCow IDs

本文探讨了如何为奶牛按升序生成特定条件的二进制编号,使用组合数学和康托展开思想来确定编号的每一位。通过枚举长度并计算组合数,算法能够高效地找到第N个符合条件的编号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
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

解释:k=1特殊处理,其他的话枚举长度,然后计算组合数不断缩小范围,同时也能确定其位的值,和康托展开思想类似

#include<iostream>
#include<cstdio>
using namespace std;
long long C[100005][12]={0};
int main(){
	ios::sync_with_stdio(false);
	for(int i=0;i<=100005;i++){
		C[i][0]=1;
		for(int j=1;j<=min(i,12);j++) C[i][j]=C[i-1][j]+C[i-1][j-1];
	}
	long long n,k;
	scanf("%lld%lld",&n,&k);
	k--;
	putchar('1');
	if(!k){
		for(int i=1;i<n;i++) putchar('0');
		return 0;
	}
	int len=k;
	while(n>1){
		if(n-C[len][k]>0){
			n-=C[len][k];len++;
		}else{
			for(int i=1;i<=len;i++){
				int sum=0;
				if(n-C[len-i][k]>0){
					n-=C[len-i][k];k--;
					sum=1;
				}
				if(sum) putchar('1');
				else putchar('0');
			}
		}
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值