數列還原 網易2017測試工程師編程題


題目:

牛牛的作業簿上有一個長度為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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM