题目描述:
题目2 : K-th string
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
Description
Consider a string set that each of them consists of {0, 1} only. All strings in the set have the same number of 0s and 1s. Write a program to find and output the K-th string according to the dictionary order. If such a string doesn’t exist, or the input is not valid, please output “Impossible”. For example, if we have two ‘0’s and two ‘1’s, we will have a set with 6 different strings, {0011, 0101, 0110, 1001, 1010, 1100}, and the 4th string is 1001.
Input
The first line of the input file contains a single integer t (1 ≤ t ≤ 10000), the number of test cases, followed by the input data for each test case.
Each test case is 3 integers separated by blank space: N, M(2 <= N + M <= 33 and N , M >= 0), K(1 <= K <= 1000000000). N stands for the number of ‘0’s, M stands for the number of ‘1’s, and K stands for the K-th of string in the set that needs to be printed as output.
Output
For each case, print exactly one line. If the string exists, please print it, otherwise print “Impossible”.
样例输入
3
2 2 2
2 2 7
4 7 47
样例输出
0101
Impossible
01010111011
思路:对于由N个0和M个1表示的二进制数,其个数有种组合情况,现在的目的是按从小到大的顺序,找出第K个组合;
代码:
#include <iostream>
#include <cmath>
using namespace std;
//计算有n位,其中0占k位时的总的个数
long long int Num_of_com(int n, int k)
{
double max_num = 1 ;
for ( int i = 0 ; i < k ; i ++)
{
max_num *= ((double)n-i)/(k-i) ; //即n*(n-1)*...*(n-k+1)/k!
}
return floor(max_num+0.0002); //floor(x)返回小于x的最大整数,是C++标准库cmath中的函数,原型只定义了double型。
}
int main(int argc,char **argv)
{
int count = 0 ; //测试数据的行数
cin >> count;
int m, n, k ; //0的个数、1的个数、第K个数
while ( count --)
{
cin >> m >> n >> k;
long long int biggest = 1 ;
char *ch = new char[m+n+1];
int ch_count = 0; //字符下标
ch[m+n] = '\0'; //字符串结束标志
biggest = Num_of_com(m+n, m) ;
//判断是否有第K个数
if ( biggest < k )
{
cout << "Impossible"<<endl;
continue;
}
int i, j;
for ( i = 1, j = 0; i <= m && j < n ; )
{
// 假设从最高位为0
biggest = Num_of_com(m-i+n-j, m-i) ;
if ( biggest > k )
{
ch[ch_count++] = '0'; //剩余位的组合数总数比K大,说明最高位为0
i ++;
}
else if ( biggest < k )
{
ch[ch_count++] = '1';
k -= biggest;
j ++;
}
else if ( biggest == k )
{
ch[ch_count++] = '0'; //当前位为0,接下来是所有剩余的1
while ( j < n )
{
ch[ch_count++] = '1';
j ++;
}
while ( i < m ) //把剩余的0添加进去
{
ch[ch_count++] = '0';
i ++;
}
}
}
//补满字符数组的剩余位
while ( ch_count < m+n )
{
ch[ch_count++] = '0';
i ++;
}
cout << ch << endl;
}
system("pause");
return 0;
}