ACM 擅長排列的小明

OpenSoucre發表於2014-04-19

擅長排列的小明

時間限制:1000 ms  |  記憶體限制:65535 KB
難度:4
 
描述
小明十分聰明,而且十分擅長排列計算。比如給小明一個數字5,他能立刻給出1-5按字典序的全排列,如果你想為難他,在這5個數字中選出幾個數字讓他繼續全排列,那麼你就錯了,他同樣的很擅長。現在需要你寫一個程式來驗證擅長排列的小明到底對不對。
 
輸入
第一行輸入整數N(1<N<10)表示多少組測試資料,
每組測試資料第一行兩個整數 n m (1<n<9,0<m<=n)
輸出
在1-n中選取m個字元進行全排列,按字典序全部輸出,每種排列佔一行,每組資料間不需分界。如樣例
樣例輸入
2
3 1
4 2
樣例輸出
1
2
3
12
13
14
21
23
24
31
32
34
41
42
43

題目就是求字串123..n的全排列的前m個字元,將123..n進行全排列,每個排列的前m個字元即為所求,注意重複的字元
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
#include <iterator>
using namespace std;

int main(){
    int N;
    cin >>N;
    while(N--){
        int n,m;
        cin >>  n >> m;
        string str = "";
        for(int i = 0 ; i < n; ++i) str+='1'+i;
        set<string> res;
        do{
            string tmp = str.substr(0,m);
            if(res.find(tmp)==res.end()) res.insert(tmp);
        }while(next_permutation(str.begin(),str.end()));
        copy(res.begin(),res.end(),ostream_iterator<string>(cout,"\n"));
    }

}

對其空間複雜度優化,不需要用set儲存每個排列,只需記住前一個排列,如果現在排列不等於前一個排列才輸出,利用next_permutation函式時按照字串大小輸出的

優化後的程式碼

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main(){
    int N;
    cin >>N;
    while(N--){
        int n,m;
        cin >>  n >> m;
        string str = "",preStr="";
        for(int i = 0 ; i < n; ++i) str+='1'+i;
        do{
            string tmp = str.substr(0,m);
            if(preStr!=tmp){
                preStr = tmp;
                cout<<preStr<<endl;
            }
        }while(next_permutation(str.begin(),str.end()));
    }
}

 

 

相關文章