题干:
我都会将理解与代码结合,希望通俗易懂的跟大家讲明白。
代码:
#include<bits/stdc++.h>
using namespace std;
int mp[10][10];
int ans,n;
int vy[10]; //列
int vd1[20];//主对角线
int vd2[20];//负对角线
void dfs(int x,int p)
{ // x:行 p:颜色的情况
/*
初步理解一下:
本题用dfs
p=1 是一种颜色
p=2 是另一种颜色
mp=1就是代表可以
mp=0就是代表不可以
*/
if(x==n&&p==2)
{
// 此处ans++满足的条件是,两个颜色(p==2)都已经搞完了(x==n)
ans++;
return ;
}
if(x==n)
{
dfs(0,p+1);
return ;
}
for(int i=0; i<n; i++)
{
if(mp[x][i]&&vy[i]!=3&&vy[i]!=p&&vd1[x+i]!=3&&vd1[x+i]!=p&&vd2[x-i+n]!=3&&vd2[x-i+n]!=p)
{
/* 这个地方也是我一开始不理解的 */
// mp=1表示符合
// !=p 是因为前面可能经历了0+p;也就是这个点前面用过了
// !=3是对于第二个颜色,因为前面可能+1了,如果再用!=p判断显然不适宜了,然后我们可以用!=3(0+=1---->1+=2)
mp[x][i]=0;
vy[i]+=p;
vd1[x+i]+=p;
vd2[x-i+n]+=p;
//调用,不用多说了
dfs(x+1,p);
//这个就是回溯
mp[x][i]=1;
vy[i]-=p;
vd1[x+i]-=p;
vd2[x-i+n]-=p;
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
scanf("%d",&mp[i][j]);
}
}
dfs(0,1);
printf("%d\n",ans);
return 0;
}