解题思路:相比看过之前的楼主写过的代码太过与繁杂,在这边的思路就是发现每一条斜线的行-行等于列-列。例如(1,1),(2,2),会发现2-1=2-1. 所以这里只需要用一维数组判断是否为同一列或者同一斜线即可(可参考bool black(white))。这里先放白皇后,利用回溯法,白皇后放过的格子定义为0表示不能再放了,先列出白皇后放的一种,然后再跳转到黑皇后放置,黑皇后放置成功到n+1行的话ans++ 表示这为第一种,然后重复以上方法即可 注意事项:用到的bool类型属于c++里面的,所以编译的时候要改为c++不然会报错 #include #include #include int map[20][20]; int n; int white1[20];//表示白皇后放过的方格 int black1[20];//表示黑皇后放过的方格 bool white(int i,int j);//判断白皇后是否可以放置 bool black(int i,int j);//同理 void dfs1(int i); int ans=0; void dfs(int i) { if(i==(n+1)) { dfs1(1); return; } for(int j=1;j<=n;j++) if(map[i][j]!=0&&white(i,j)) { white1[i]=j; map[i][j]=0;//这边注意的是每次都会回溯直到白皇后被成功放置,然后跳转到黑皇后放置完,白皇后再回溯 dfs(i+1); map[i][j]=1; } } void dfs1(int i) { if(i==(n+1)) { ans++; return; } for(int j=1;j<=n;j++) if(map[i][j]!=0&&black(i,j)) { black1[i]=j; dfs1(i+1); } } bool white(int i,int j) { if(i==1) return true; for(int k=1;k<i;k++) if(white1[k]==j||abs(i-k)==abs(j-white1[k])) { return false; } return true; } bool black(int i,int j) { if(i==1) return true; for(int k=1;k<i;k++) if(black1[k]==j||abs(i-k)==abs(j-black1[k])) { return false; } return true; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&map[i][j]); dfs(1); printf("%d",ans); return 0; }
0.0分
3 人评分