(下一个排列改编题)每次写蓝桥上面的题总有莫名的火气--难以理解题意

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(下一个排列改编题)每次写蓝桥上面的题总有莫名的火气--难以理解题意相关的知识,希望对你有一定的参考价值。

题目

题目分析

开始看完后,理解题意:j 不能出现在 i 前面,没错,我就是这么理解的,然后看数据量不大,就写了个 dfs ,用两层vector存下 j 前面不能出现的数,然后 dfs 检查性的递归实现,结果???结果他这道题的题意是:只需要检查前面一个位与当前位是否互斥?

  • 花了挺多时间的,讲实话,主要就是这个题目描述真的离谱。

复杂dfs,按最开始理解的题意写的。。果不其然错了

#include<bits/stdc++.h>
using namespace std;
int n,k;
//用一个数组方便记录这个数前面不能取哪些数
vector<vector<int> >mp(11);
//用一个map记录每次前面已经取过的数字,由于数据量小故可用数组代替;
bool check[11] = {false};
vector<int>res;
int times = 0;
void dfs(int pos){
  if(pos==n){
    times++;
    if(times==k)
      for(int i=0;i<n;i++){
        cout<<res[i]<<' ';
      }
    return;
  }

  for(int i=0;i<n;i++){
    if(check[i]||times>=k)
      continue;
      //检查前面是否已经取过取该数时不能取的数
    vector<int>& s = mp[i];
    if(s.size()){
      bool f = false;
      for(int j=0;j<s.size();j++){
        if(check[s[j]]){
            f = true;
              break;
        }
      }
      if(f)
        continue;
    }
    //记录已取数字
    res.push_back(i);
    check[i] = true;
    dfs(pos+1);
    check[i] = false;//撤销回溯
    res.pop_back();
  }
}

int main(){
  
  cin>>n>>k;
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      int t;
      cin>>t;
      //建立j前面不能出现i的关系表
      if(i!=j&&t==0){
        mp[j].push_back(i);
      }
    }
  }
 
}
  • 后面还写了几版递归的排列过程(有哈希表法和swap方法两种),在中间剪枝得到答案,不过最后并没有实现,还是用的 next_permutation 的方式写完的。

最终解题代码

应该都能看懂,就不写说明了

#include<bits/stdc++.h>
using namespace std;
int n,k;
//讲道理有种被坑的感觉。。。这道题仅仅只是需要查询相邻位置是否互斥。。
//就在排列的过程中检查一下下一个位要成为的值和当前位的值 是否互斥即可
//故其实只需要一个检查函数
int mp[11][11];
int times = 0;
bool check(vector<int>& t){
    for(int i=1;i<t.size();i++){
        if(!mp[t[i-1]][t[i]])
            return false;
    }
    return true;
}
int main(){

    cin>>n>>k;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>mp[i][j];
        }
    }
    vector<int>res(n);
    for(int i=0;i<n;i++) res[i] = i;
    while(1){
        if(check(res))
            times++;
        if(times==k)
            break;
        next_permutation(res.begin(),res.end());
    }
    for(int i=0;i<res.size();i++){
        cout<<res[i]<<' ';
    }
}

以上是关于(下一个排列改编题)每次写蓝桥上面的题总有莫名的火气--难以理解题意的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯 排列序数 2014年JavaB组决赛第4题

蓝桥杯上的一题,题目为排列数,用了暴力算法超时,请问该怎么处理,谢谢!

java算法 蓝桥杯(题+答案) 煤球数目

《面向对象程序设计》第一次作业

java算法 蓝桥杯(题+答案) 抽签

第十二届蓝桥杯C++赛后感