微软2014实习生招聘在线测试第2题——K-th string

题目描述:

题目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”. 
 
样例输入 

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值