zoukankan      html  css  js  c++  java
  • 数列还原 网易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 }
  • 相关阅读:
    python实现清屏
    列表/字典/集合解析式和生成器
    SQL——pivot的用法
    前端的3大类描述
    2019-耦合性斗争笔记
    前端基础语法
    解决winform在win10下字体模糊的问题
    Xamarin.Android打包设置
    N0---我的编程教学提纲
    N0---关于变量
  • 原文地址:https://www.cnblogs.com/hslzju/p/5743569.html
Copyright © 2011-2022 走看看