下午写的这个题。 用回溯写的。 各种WA。 总是找不出 BUG。
晚上喝 峰哥 楷神 出去吃了个烧烤。 回来一想就找出 BUG 然后A了。 爽歪歪。
这个题 我思路是比较习惯横向的 所以我先把纵向判断 反向 调换之后 改成横向。
写回溯 肯定不会超时。 数据太小。 就直接爆了。 但是交上去是WA了。 就感觉 不会改了。 找了好几遍BUG 没找到。
最后终于想到了。 我没有出样例。 只是想到了 某一个特殊情况 而改出来的。
举例吧
A A A A A
B B B B B
C C C C C
D D D D D
E E E E E
F F F F F
A A A A A
A B B B B
C C C C C
D D D D D
E E E E E
F F F F F
唯一不同就是 第二行 把B变成了A 那么在后面 就可能某第 k个 与 第1 个相同。 注意在 筛选的时候 如果有相同的元素 去重就可以了
上代码。 我用 set 实现的去重。 用vector 保存的 字符 (比数组方便的多) string 保存路径
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
#define ll long long
typedef unsigned long long ull;
#define maxn 1000+10
#define INF 1<<30
int n;
int sum = 0;
char s1[100][100],s2[100][100];
vector <char> ss1[maxn];
vector <char> ss2[maxn];
int dfs(int h,int num,string s){
if(num == 5){
sum ++;
if(sum == n){
cout << s <<endl;
return 1;
}
return 0;
}
else {
for(int j = 0; j < ss1[h].size(); j++){
for(int k = 0; k < ss2[h].size(); k++){
if(ss1[h][j] == ss2[h][k]){
if(dfs(h+1,num+1,s + ss1[h][j]))
return 1;
}
}
}
}
return 0;
}
int main (){
int counts;
scanf("%d",&counts);
while(counts--){
scanf("%d",&n);
sum = 0;
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
for(int i = 0; i < 6; i++)
scanf("%s",s1[i]);
for(int i = 0; i < 5; i++)
ss1[i].clear();
set <char> q1[maxn];
for(int i = 0; i < 5; i++){
for(int j = 0; j < 6; j++){
if(!q1[i].count(s1[j][i])){
ss1[i].push_back(s1[j][i]);
q1[i].insert(s1[j][i]);
}
}
sort(ss1[i].begin(),ss1[i].end());
}
set <char> q2[maxn];
for(int i = 0; i < 6; i++)
scanf("%s",s2[i]);
for(int i = 0; i < 5; i++)
ss2[i].clear();
for(int i = 0; i < 5; i++){
for(int j = 0; j < 6; j++){
if(!q2[i].count(s2[j][i])){
ss2[i].push_back(s2[j][i]);
q2[i].insert(s2[j][i]);
}
}
sort(ss2[i].begin(),ss2[i].end());
}
int flag = 0;
for(int j = 0; j < ss1[0].size(); j++){
for(int k = 0; k < ss2[0].size(); k++){
if(ss1[0][j] == ss2[0][k]){
string s;
if(dfs(1,1,s + ss1[0][j])){
flag = 1;
break;
}
}
}
if(flag)
break;
}
if(!flag)
printf("NO\n");
}
return 0;
}
然后回溯就很简单了。
本文分享了一个使用回溯算法解决特定问题的经历,通过调整思路和排查bug最终成功解决了问题。文章详细记录了从横向到纵向的转换过程,并展示了如何利用set进行有效去重,确保搜索路径的正确性。

750

被折叠的 条评论
为什么被折叠?



