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