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 }
  • 相关阅读:
    封装成帧、帧定界、帧同步、透明传输(字符计数法、字符串的首尾填充法、零比特填充的首尾标志法、违规编码法)
    计算机网络之数据链路层的基本概念和功能概述
    物理层设备(中继器、集线器)
    计算机网络之传输介质(双绞线、同轴电缆、光纤、无线电缆、微波、激光、红外线)
    计算机网络之编码与调制
    0953. Verifying an Alien Dictionary (E)
    1704. Determine if String Halves Are Alike (E)
    1551. Minimum Operations to Make Array Equal (M)
    0775. Global and Local Inversions (M)
    0622. Design Circular Queue (M)
  • 原文地址:https://www.cnblogs.com/hslzju/p/5743569.html
Copyright © 2011-2022 走看看