数列还原 网易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 }
-------------------------------------------------
原创博客 转载请注明出处http://www.cnblogs.com/hslzju
-------------------------------------------------