下午写的这个题。 用回溯写的。 各种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;
}
然后回溯就很简单了。