题目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”.


样例输入
3
2 2 2
2 2 7
4 7 47
样例输出
0101
Impossible
01010111011
解题思路:用到了stl中的next_permutation思想,然后对其进行了稍微的修改。

next_permutation
首先,从最尾端开始往前寻找两个相邻元素,令第一元素为*i,第二元素为*ii,且满足*i < *ii。找到这样一组相邻元素后,再从尾端开始往前查找,

找出第一个大于*i的元素,令为*j,将i,j元素对调,再将ii及之后的所有元素颠倒排列。此时即为所求之“后一个”排列组合。


//source here
#include <iostream>
#include <vector>
#include <string>

using namespace std;

bool next_permutation(vector<char> &num){
	int i, ii, j;
        
	int len = num.size();
	if(len == 1) return false;
	if(len == 2) {
		swap(num[0], num[1]);
		return true;
	}
	ii = i = 0;
	int tmpK = 1;
	for(int k = len - 1; k > 0; k--){
		tmpK = k;
		if(num[k] > num[k - 1]){
			ii = k;
			i = k - 1;
			break;
		}
	}
	if(1 == tmpK){
		if(num[i] >= num[ii]) return false;
	}
	if(i == ii){
		int b = 0, e = len - 1;
		while(b < e){
			swap(num[b], num[e]);
			b++; e--;
		}
		return false;
	}
	for(int k = len - 1; k > 0; k--){
		if(num[k] > num[i]) {
			j = k;
			break;
		}
	}
	swap(num[i], num[j]);
	while(ii < len - 1){
		swap(num[ii], num[len - 1]);
		ii++; len--;
	}
	return true;
}

string findKthNum(vector<char> &num, int k){
	for(int i = 0; i < k - 1; i++){
		if(!next_permutation(num)) return "Impossible";
	}
	
	return string(num.begin(), num.end());
}

int main(){
	vector<vector<int> > vvi;
	int t;
	int n, m;
	int k;

	while(cin >> t){
		for(int i = 0; i < t; i++){
			cin >> n >> m >> k;
			vector<int> vi(3, 0);
			vi[0] = n, vi[1] = m, vi[2] = k;
			vvi.push_back(vi);		
		}
		for(int i = 0; i < t; i++){
			n = vvi[i][0];
			m = vvi[i][1];
			k = vvi[i][2];
			vector<char> num(n + m, '1');
			for(int j = 0; j < n; j++) num[j] = '0';
			cout << findKthNum(num, k) << endl;
		}
	}
	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值