描述
给定一个 n*n 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 n 个黑皇后和 n 个白皇后,使任意的两个黑皇后都不在同一行、
同一列或同一条斜线(包括正负斜线)上,任意的两个白皇后都不在同一行、同一列或同一条斜线(包括正负斜线)上。问总共有多少种放法?n
小于等于 8。
输入输出格式
输入
输入的第一行为一个整数 n,表示棋盘的大小。接下来 n 行,每行 n 个 0 或 1 的整数,如果一个整数为1,表示对应的位置可以放皇后,如
果一个整数为 0,表示对应的位置不可以放皇后。
输出
输出一个整数,表示总共有多少种放法。
输入输出样例
输入样例 1
4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
输出样例 1
2
输入样例 2
4 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
输出样例 2
2
解题思路
这题本质和N皇后差不多,只需要找到黑皇后的一种方法后再找白皇后的方法,并使得黑白皇后不在同一格且再加上了一个限制而已。(不会
N皇后的同学可以先去看一看)
题解
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,num=0;
4 bool l[10001];
5 bool x[10001];
6 bool y[10001];//黑皇后的判断
7
8 bool l_[10001];
9 bool x_[10001];
10 bool y_[10001];//白皇后的判断
11 bool mp[10001][10001];//公用地图
12 void queenW(int ans);
13 void queenB(int ans)//黑皇后搜索
14 {
15 if(ans==n+1)
16 {
17 queenW(1);//如果找到了一个方法,就搜索白皇后
18 return;
19 }
20 for(int j=1;j<=n;j++)
21 {
22 if(!l[j]&&!x[ans-j]&&!y[ans+j]&&mp[ans][j])//判断
23 {
24 l[j]=true;
25 x[ans-j]=true;
26 y[ans+j]=true;
27 mp[ans][j]=false;//标记并且标记地图
28 queenB(ans+1);//下一个皇后
29 l[j]=false;
30 x[ans-j]=false;
31 y[ans+j]=false;
32 mp[ans][j]=true;//回溯(取消标记)
33 }
34 }
35 return;
36 }
37 void queenW(int ans)//白皇后搜索
38 {
39 if(ans==n+1)//如果找到了,方案加一
40 {
41 num++;
42 }
43 for(int j=1;j<=n;j++)
44 {
45 if(!l_[j]&&!x_[ans-j]&&!y_[ans+j]&&mp[ans][j])//有没有与其他白皇后冲突且这一格没有黑皇后并且能放
46 {
47 l_[j]=true;
48 x_[ans-j]=true;
49 y_[ans+j]=true;//标记
50 queenW(ans+1);//下一个皇后
51 l_[j]=false;
52 x_[ans-j]=false;
53 y_[ans+j]=false;//回溯(取消标记)
54 }
55 }
56 return;
57 }
58 int main()
59 {
60 cin>>n;
61 for(int i=1;i<=n;i++)
62 {
63 for(int j=1;j<=n;j++)
64 {
65 cin>>mp[i][j];//输入限制
66 }
67 }
68 queenB(1);//从黑皇后开始搜
69 cout<<num;
70 return 0;
71 }