題目:
牛牛的作業簿上有一個長度為n的排列A,這個排列包含了從1到n的n個數,但是因為一些原因,其中有一些位置(不超過10個)看不清了,但是牛牛記得這個數列順序對的數量是k,順序對是指滿足i<j且A[i]<A[j]的對數,請幫助牛牛計算出,符號這個要求的合法排列數目。輸入n,k與序列A,返回可能的存在排列數目。
輸入描述:
每個輸入包含一個測試用例。每個測試用例的第一行包含兩個整數n和k(1<=n<=100,1<=k<=1000000000),接下來的一行,包含n個數字表示排列A,其中等於0的項表示看不清額位置(不超過10個)。
輸出描述:
輸出一行表示合法排列的數目。
輸入例子:
5 5
4 0 0 2 0
輸出例子:
2
方法一:通過
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <queue> 5 #include <unordered_map> 6 #include <map> 7 #include <algorithm> 8 using namespace std; 9 10 //輸入參數 11 int n;//輸入n個數 12 int k;//有序對k對 13 vector<int> a;//輸入序列a,包含1~n的n個數,有若干個數(不超過10個)是0 14 //輸出參數 15 int cnt=0;//合法排列的數目 16 17 //輸出perm數組,用於測試 18 void printperm(const vector<vector<int> > &perm) 19 { 20 for(int i=0;i<perm.size();i++) 21 { 22 for(int j=0;j<perm[0].size();j++) 23 cout<<perm[i][j]<<" "; 24 cout<<endl; 25 } 26 } 27 28 //第一步,選出用於全排列的數 29 void chooseperm(vector<int> &permuse) 30 { 31 vector<int> permtemp; 32 int permnum=0;//需要全排列的數的個數 33 int temp=0; 34 for(int i=1;i<=n;i++)//初始化為1~n 35 permtemp.push_back(i); 36 for(int i=0;i<a.size();i++)//移除輸入中已有的數 37 { 38 if(a[i]) 39 { 40 remove(permtemp.begin(),permtemp.end(),a[i]); 41 temp++; 42 } 43 } 44 permnum=n-temp;//n-移除的數,即需要全排列的數的個數 45 for(int i=0;i<permnum;i++)//得到用於全排列的vector 46 permuse.push_back(permtemp[i]); 47 } 48 49 //第二步,對第一步選出的數全排列 50 void creatperm(vector<vector<int> > &perm,vector<int> &permuse) 51 { 52 do{ 53 perm.push_back(permuse); 54 }while(next_permutation(permuse.begin(), permuse.end())); 55 } 56 57 //第三步,拼接第二步得到的全排列的二維vector和已有的輸入 58 void insertperm(vector<vector<int> > &perminsert,const vector<vector<int> > &perm) 59 { 60 for(int i=0;i<perm.size();i++) 61 { 62 vector<int> tempinsert; 63 int q=0; 64 for(int p=0;p<n;p++) 65 { 66 if(a[p]) 67 tempinsert.push_back(a[p]); 68 else 69 tempinsert.push_back(perm[i][q++]); 70 } 71 perminsert.push_back(tempinsert); 72 } 73 74 } 75 76 //第四步,逐行驗證其有序對是否為k,統計符合的個數 77 void count( const vector<vector<int> > &choose) 78 { 79 for(int i=0;i<choose.size();i++) 80 { 81 int ktemp=0; 82 vector<int> temp=choose[i]; 83 for(int j=0;j<temp.size();j++) 84 { 85 for(int jj=j+1;jj<temp.size();jj++) 86 { 87 if(temp[j]<temp[jj]) 88 ktemp++; 89 } 90 } 91 if(ktemp==k) 92 cnt++; 93 } 94 } 95 96 int main(){ 97 //輸入 98 cin>>n>>k; 99 for(int i=0;i<n;i++) 100 { 101 int temp; 102 cin>>temp; 103 a.push_back(temp); 104 } 105 106 //第一步,選出用於全排列的數 107 vector<int> permuse;//用於全排列的數 108 chooseperm(permuse); 109 // cout<<"用於全排列的數"<<endl; 110 // for(int i=0;i<permuse.size();i++) 111 // cout<<permuse[i]<<" "; 112 // cout<<endl; 113 114 //第二步,對第一步選出的數全排列 115 vector<vector<int> > perm;//得到全排列的二維vector 116 creatperm(perm,permuse); 117 // cout<<"全排列"<<endl; 118 // printperm(perm); 119 120 //第三步,拼接第二步得到的全排列的二維vector和已有的輸入 121 vector<vector<int> > perminsert; 122 insertperm(perminsert,perm); 123 // cout<<"符合模板的排列"<<endl; 124 // printperm(perminsert); 125 126 //第四步,逐行驗證其有序對是否為k,統計符合的個數 127 count(perminsert); 128 // cout<<"符合的排列個數"<<endl; 129 cout<<cnt<<endl; 130 }
方法二:內存超限:您的程序使用了超過限制的內存
一開始想到的是方法二,方法一是后來改進的,所以也貼出來
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 //輸入參數 7 int n;//輸入n個數 8 int k;//有序對k對 9 vector<int> a;//輸入序列a,包含1~n的n個數,有若干個數(不超過10個)是0 10 //輸出參數 11 int cnt=0;//合法排列的數目 12 13 //輸出perm數組,用於測試 14 void printperm(const vector<vector<int> > &perm) 15 { 16 for(int i=0;i<perm.size();i++) 17 { 18 for(int j=0;j<perm[0].size();j++) 19 cout<<perm[i][j]<<" "; 20 cout<<endl; 21 } 22 } 23 24 //將1~n全排列,放入二維數組perm 25 void creatperm(vector<vector<int> > &perm) 26 { 27 vector<int> temp;//1~n的臨時vector 28 for(int i=1;i<=n;i++) 29 temp.push_back(i); 30 do{ 31 perm.push_back(temp); 32 }while(next_permutation(temp.begin(), temp.end())); 33 } 34 35 //過濾,刷掉返回false,如果沒有刷掉返回true 36 bool chooseperm(const vector<int> &permtemp) 37 { 38 for(int i=0;i<n;i++) 39 { 40 if(a[i]) 41 { 42 if(a[i]!=permtemp[i]) 43 return false; 44 } 45 } 46 return true; 47 } 48 49 //計算cnt 50 void count( const vector<vector<int> > &choose) 51 { 52 for(int i=0;i<choose.size();i++) 53 { 54 int ktemp=0; 55 vector<int> temp=choose[i]; 56 for(int j=0;j<temp.size();j++) 57 { 58 for(int jj=j+1;jj<temp.size();jj++) 59 { 60 if(temp[j]<temp[jj]) 61 ktemp++; 62 } 63 } 64 if(ktemp==k) 65 cnt++; 66 } 67 } 68 69 int main(){ 70 //輸入 71 cin>>n>>k; 72 for(int i=0;i<n;i++) 73 { 74 int temp; 75 cin>>temp; 76 a.push_back(temp); 77 } 78 79 //第一步 80 //先將1~n全排列(permutation),生成一個二維數組備用(每一行代表一種排序方式); 81 vector<vector<int> > perm;//用於存放全排列的二維vector 82 creatperm(perm); 83 // cout<<"全排列:"<<endl; 84 // printperm(perm);//測試生成是否正確 85 86 //第二步 87 //過濾該二維數組,選取滿足特定位置上為輸入序列中非0數的序列,生成新的二維數組; 88 vector<vector<int> > choose;//過濾之后的二維數組 89 for(int i=0;i<perm.size();i++) 90 { 91 if(chooseperm(perm[i])) 92 choose.push_back(perm[i]); 93 } 94 // cout<<"過濾后:"<<endl; 95 // printperm(choose);//測試生成是否正確 96 97 //第三步 98 //逐行驗證其有序對是否為k,統計符合的個數; 99 count(choose); 100 // cout<<"符合的排列個數:"<<endl; 101 cout<<cnt<<endl; 102 }