纪中暑假集训 2020.08.08【NOIP提高组】模拟 T1:【NOIP2012模拟8.7】奶牛编号

【NOIP2012模拟8.7】奶牛编号

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

反思&题解

比赛&正解思路: 用组合数求出答案串长度,对于一个有k个1的串,那么它的第一位肯定是1,然后再用组合数判断后面几位怎么填就行了,不过 n = 1 n=1 k = 1 k=1 的情况要打个表(比赛的时候不知道哪里打炸了,只有20分,重新删掉打一遍就过了……)
反思: 代码细节问题要多注意

CODE

#include<bits/stdc++.h>
using namespace std;
long long n,k,c[5005][35],tot,tot1;
int main()
{
	long long i,j;
	for (i=0;i<=5000;i++)
		c[i][0]=1;
	for (i=1;i<=5000;i++)
	{
		for (j=1;j<=30;j++)
			c[i][j]=c[i-1][j]+c[i-1][j-1];
	}
	scanf("%lld%lld",&n,&k);
	if (n==1)
	{
		for (i=1;i<=k;i++)
			printf("1");
		printf("\n");
		return 0;
	}
	if (k==1)
	{
		printf("1");
		for (i=1;i<n;i++)
			printf("0");
		printf("\n");
		return 0;
	}
	tot=k;
	while (c[tot][k]<=n) tot++;
	tot--;
	k--;
	printf("1");
	for (i=k;i<tot;i++)
		n-=c[i][k];
	for (i=1;i<=tot;i++)
	{
		if (k==0) printf("0");
		else if (c[tot-i][k]>=n) printf("0");
		else
		{
			printf("1");
			n-=c[tot-i][k];
			k--;
		}	
	}
	printf("\n");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/CMC_YXY/article/details/107880640