微软2014在线笔试第二题 (对于问题中的k是有限制的,取值范围是1~9)

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 s​uch 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”. 

ps:这里面要求的K的取值是[1,1000000000],博主的程序限定了K的取值范围,改为[1,9]。

#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAXWORDS 30000
#define NUM 18

void string_process(int s[], int start);
int countones(int tar_num);

int main()
{

	char test_number[6];
	char c;
	int i, j, k, num ,tmp;
	int test_cases[MAXWORDS];
	int test[3];

	memset(test_number, '*', sizeof(test_number));

	//******************************************************输入数据****************************************//
	printf("INPUT THE TEST CASES NUMBER YOU WANT  PS:it must ranged from 1 to 10000\n");
	i =0;
	while((c = getchar()) != '\n')
	{
		test_number[i] = c;
		i++;
	}
	
	i = 0;
	while(test_number[i] != '*')
	{
		i++;
	}

	num = 0;
	tmp = i;
	for ( j = 0; j < tmp; j++)
	{
		num = num + (test_number[j] - '0') * (int)pow(10, (int)(--tmp));
	}

	printf("the test cases number you want is %d\n", num);

	k = 0;

	for (i = 0; i < num; i++)
	{
		printf("INPUT THE %d th test case:\n", i+1);
		j = 0;
		while((c = getchar()) != '\n')
		{
			test[j] = c - '0';
			j++;
		}

		for (j = 0; j<3; j++)
		{ 
			test_cases[k] = test[j];
			k++;
		}
	}

	tmp = k;
//***************************************************处理数据***********************************//
	for (i = 0; i < num;i++)
	{
		printf("the %d th answer is :\n", i);
		string_process(test_cases, i*3);
	}
	return 0;
}

void string_process(int s[], int start)
{
	int i, j;
	int sum , min, max;
	int num_0 = s[start];
	int num_1 = s[start+1];
	int num = num_0 + num_1;
	int k;
	int k_number;
	int a[NUM];
	int m = num_0;
	int n = num_1;
	sum = jiecheng(m ,n);

	if(s[start+2]>sum)
	{
		printf("IMPOSSIBLR\n");
		return;
	}
	max = 0;
	j = num;
	min = 0;
	k = 0;
	for (i = 0; i < num_1; i++)
	{
		max = max + (int)pow(2,--j);
		min = min + (int)pow(2,i);
	}

	for(i = min; i <= max; i++)
	{
		if ((j = countones(i)) == num_1)
		{
			k++;
			if (k == s[start + 2])
			{
				k_number = i;
			}
		}
	}

	i = 0;
	while(1)
	{
		a[i] = k_number%2;
		k_number = k_number/2;
		if (k_number == 0)
		{
			break;
		}
		i++;
	}
	while ((num-1) > i)
	{
		printf("0");
		num--;
	}
	for (j = i; j >=0; j--)
	{
		printf("%d", a[j]);
	}
	printf("\n");

}

int countones(int tar_num)
{
	int count = 0;
	while(tar_num != 0)
	{
		tar_num = tar_num & (tar_num -1);
		count++;
	}
	return count;
}

int jiecheng(int m, int n)
{
	int c, sum;
	int i;
	c = m + n;

	sum = 1;
	for(i = 0; i < m;i++)
	{
		sum = sum * c;
		c--;
	}

	for (i = 0; i < m;i++)
	{
		sum = sum / m;
		m--;
	}

	return sum;
}


重要函数——int conutones(int n):该函数的作用是算出一个整数的二进制形式包含多少个1

其中,如下一段代码表示将十进制转化为二进制,并打印出来:

	i = 0;
	while(1)
	{
		a[i] = k_number%2;
		k_number = k_number/2;
		if (k_number == 0)
		{
			break;
		}
		i++;
	}
	while ((num-1) > i)
	{
		printf("0");
		num--;
	}
	for (j = i; j >=0; j--)
	{
		printf("%d", a[j]);
	}
	printf("\n");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值