数列还原 网易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 }
posted @ 2016-08-06 11:15  Pearl_zju  阅读(1443)  评论(2编辑  收藏  举报