微软2014实习生及秋令营技术类职位在线测试-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

分析

获取0数目为N,1数目为M的组合数目可以根据公式F(N,M)=F(0,M-1)+F(1,M-1)+…+F(N,M-1),设计好收敛条件。从小累加判断是否大于K,输出确定部分。循环判断剩余部分。使用hash表提高效率。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<hash_map>
using namespace std;
hash_map<int, int> map;
hash_map<int, int>::iterator it;
int getCount(int zeorN, int oneN);
int main()
{
    int N,M,K;
    cin >> N >> M>>K;
    int n = 0;
    int count = 0;
    bool get = false;
    while (!get&&n<=N){

        int tg =  getCount(n, M-1);
        if (count + tg <K){
            count = count + tg;
            n++;
        }
        else if (count + tg>K){
            for (int i = 0; i < (N - n); i++)cout << "0";
            cout << "1";
            N = n;
            n = 0;
            M--;
        }
        else{
            for (int i = 0; i < (N - n); i++)cout << "0";
            for (int i = 0; i < M; i++)cout << "1";
            for (int i = 0; i < n; i++)cout << "0";

            get = true;
        }

    }
    if (!get)cout << "Impossible";
    cout << endl;
    return 0;
}
int getCount(int zeroN, int oneN){
    if (oneN < 0)return 0;
    if (oneN == 0|| zeroN==0)return 1;
    if (zeroN == 1)return 1 + oneN;
    int count = 0;
    while (zeroN >= 0){
        int hashcode = zeroN * 34 + oneN - 1;
        it = map.find(hashcode);
        int gc;
        if (it == map.end()){
            gc = getCount(zeroN, oneN - 1);
            map[hashcode] = gc;
        }
        else{
            gc = it->second;
        }
        count = count + gc;
        zeroN--;
    }
    return count;
}
点赞