JAVA動態規劃(四)--根據給定0和1的個數,求字典序排在第K位的數【微軟筆試題】

題目:
Time Limit: 10000ms
Case Time Limit: 1000ms
Memory Limit: 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 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”.
Sample In
3
2 2 2
2 2 7
4 7 47
Sample Out
0101
Impossible
01010111011
簡單來說就是:給定n個 0和m 個1,求字典排序的第 k個值。【這是微軟MicroSoft之前校招的一道筆試題】

分析:用d[i][j]表示由i個0,j個1最能能夠組合的數,則狀態轉移方程爲:d[i][j]=d[i-1][j]+d[i][j-1];

如果最高位是0的組合數大於等於K(dp[n][m-1] >= K), 那麼最高爲一定爲0。
如果最高位是0的組合數小於K, 那麼最高位一定爲1。 此時,應該減去最高位爲0的前一半的數,最高位爲0的組合有dp[n-1][m]個,問題變成:在N個0和(M-1)個1中需要爲(K-dp[n][m-1])的數字是多少。

package dynamic_programming;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
 * @author Gavenyeah
 * @date Time: 2016年4月5日下午5:05:10
 * @des: 
 */
//d[i][j]表示由i個0,j個1最能能夠組合的數
//則狀態轉移方程爲:d[i][j]=d[i-1][j]+d[i][j-1];
public class FindKthString {
    List<String>set=new ArrayList<String>();

    public static void main(String[] args) {
        FindKthString te=new FindKthString();
        te.getString();
        te.printSet();
    }
    public void getString(){ //多組輸入,輸入結束了,一次輸出
        Scanner in=new Scanner(System.in);
        int t=in.nextInt();
        for(int r=0;r<t;r++){
            int n=in.nextInt();
            int m=in.nextInt();
            int k=in.nextInt();
            int dp[][]=getDpArray(n, m);
            findKString(n,m,k,dp);
        }
        in.close();
    }

    public void findKString(int n,int m,int k,int d[][]){ //找到排在第k位上的數
        StringBuffer s=new StringBuffer();
        if(k>d[n][m]){
            set.add("Impossible");
        }else{
            while(k>0&&n>0){
                if(d[n-1][m]>=k){
                    s.append("0");
                    n--;
                }else {
                    s.append("1");
                    k=k-d[n-1][m];//最高位爲1時,減去前面的最高位爲0 的數
                    m--;//此時1的個數減1
                }
            }
            while(m>0){
                s.append("1");
                m--;
            }
            set.add(s.toString());
        }
    }

    public int[][] getDpArray(int n,int m){
        int[][]d=new int[n+1][m+1];
        for(int i=1;i<=n;i++){
            d[i][0]=1;
        }
        for(int j=1;j<=m;j++){
            d[0][j]=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                d[i][j]=d[i-1][j]+d[i][j-1];
            }
        }
        return d;
    }
    public void printSet(){
        while(!set.isEmpty()){
            System.out.println(set.remove(0));
        }
    }
    /*public void findKString(int n,int m,int k){
        int len=m+n;
        int[]a=new int[len];
        for(int i=0;i<m;i++){
            a[i]=1;
        }
        getPermutations(a,0,len-1);
        if(k<1||k>set.size()){
            list.add("Impossible");
        }else{
            Iterator<String>iter=set.iterator();
            while(k>1){
                iter.next();
                k--;
            }
            String str=iter.next();
            list.add(str);
        }
        set.clear();
    }
    public void getPermutations(int a[],int p,int q){
        if(p==q){
            String buf=new String();
            for(int j=0;j<=q;j++){
                buf=buf+a[j];
            }
            set.add(buf);
        }
        else{
            for(int i=p;i<=q;i++){
                swap(a,i,p);
                getPermutations(a,p+1,q);
                swap(a,i,p);
            }
        }
    }
    public void swap(int a[],int p,int q){
        int temp=a[p];
        a[p]=a[q];
        a[q]=temp;
    }*/
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章