ABC Puzzle题解——DFS
D - ABC Puzzle 题解
这是一个大模拟的DFS题,写一下题解吧,目前只有我自己这个能理解
1.4种情况模拟,不选,选abc
2.剪枝,若单行内不满足有3个,剪掉
3.判断,先判断首字母,再判断重复,因为>3且无重复的话,就可以通过
#include <bits/stdc++.h>
using namespace std;
int n;
string a,b;
int ma[20][20];
int visx[100][100],visy[100][100],visx_first[100],visy_first[100];
bool out=0;
void check() {
bool logo=false;
memset(visx_first,0,sizeof(visx_first));
memset(visy_first,0,sizeof(visy_first));
for(int i=1;i<=n;i++) {
for(int j=1;j<=n;j++) {//横纵判断
if (ma[i][j]!=0&&visx_first[i]==0) {
visx_first[i]=ma[i][j];
}
if (ma[i][j]!=0&&visy_first[j]==0) {
visy_first[j]=ma[i][j];
}
//用来存储首行内容
if (visx[i][ma[i][j]]>1) {
logo=true;
}
if (visy[j][ma[i][j]]>1) {
logo=true;
}//用来判断是否有重复
if (visx[i][ma[i][j]]==0&&ma[i][j]!=0) {
visx[i][ma[i][j]]++;
}
if (visy[j][ma[i][j]]==0&&ma[i][j]!=0) {
visy[j][ma[i][j]]++;
}//记录数据
}
}
for(int i=1;i<=n;i++) {
if (visx_first[i]!=a[i]-'A'+1) {
logo=true;
}
if (visy_first[i]!=b[i]-'A'+1) {
logo=true;
}//看看首行首列是否相等
}
if (logo==0) {//无问题
cout<<"Yes"<<endl;
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) {
if (ma[i][j]==0) {
cout<<'.';
}
else {
cout<<char(ma[i][j]+'A'-1);
}
}
cout<<endl;
}
exit(0);
}
}
bool visabc[10][10], visabc1[10][10];
void dfs(int x,int y,int num) {
if (y>n) {
if (num<3) {//剪枝,若一行完了不够3个数,就不选了
return;
}
dfs(x+1,1,0);
return;
}
if (x>n) {
check();
return;
}
if (num<=3) {
for (int i=1; i<=3; i++) {
if (visabc[x][i]==0&&visabc1[y][i]==0) {//首行首列的字母i没用过
visabc[x][i]=1;
visabc1[y][i]=1;
ma[x][y] = i;
dfs(x,y+1,num+1);
ma[x][y] = 0;
visabc[x][i]=0;
visabc1[y][i]=0;
}
}
}
dfs(x,y+1,num);
return;
}
int main() {
cin>>n;
cin>>a>>b;
a = ' '+a;
b = ' '+b;//空出首位
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
ma[i][j] = 0;
}
}
dfs(1,1,0);//1,1开始,选了0个
if (out==0) {
cout<<"No";
}
return 0;
}
本题两难点
1.剪枝考虑,若无num<3不录入,就会多很多判断与情况
2.判断模拟

浙公网安备 33010602011771号