2n皇后问题

2n皇后问题是典型的抽象深度遍历的题目,在这种抽象遍历的题目里,我们有大量的约束条件。先看题:

 

 

 

 

 

解题的关键是要想到怎么遍历,如这题选择的是以每一行作为一个度来遍历(也就是dfs_b遍历函数里的参数),每一行选择后这一行就不会再添加皇后,

因此把“每一行不能出现同种颜色的皇后”这个条件解决了。对每一行开始选择对列进行遍历,把其它条件都在列里面解决了,这就把所有条件考虑到了。

还有就是,我考虑的是先添加黑皇后再添加红皇后,也可以两个一起考虑,但是那样的话要遍历更多次。

 1 #include<iostream>
 2 #include<math.h>
 3 using namespace std;
 4 int n;
 5 int map[10][10];//地图 
 6 int qw[10],qb[10];//qw[i]=j表示白皇后在i行j列。 
 7 int vis[10][10];//地图存放过皇后的状态 
 8 int ans=0;//可行方案的数量 
 9 bool q_in(int x,int y,int q[])
10 {
11     if(vis[x][y]==1||map[x][y]==0)
12     {    
13         return false;
14     }
15     else
16     {
17         for(int i=1;i<x;++i)
18         {
19             if(y==q[i]||abs(i-x)==abs(q[i]-y))//这个abs是关键 
20                 return false;                // 把“斜对角不能有相同颜色的皇后”  
21         }                                    // 这个条件解决了 
22         return true;
23     }
24 }
25 void dfs_w(int x)
26 {
27     if(x==n+1)
28     {
29         ans++;
30         return ;
31     }
32     else{
33         for(int i=1;i<=n;++i)
34         {
35             if(q_in(x,i,qw)==true)
36             {
37                 qw[x]=i;
38                 vis[x][i]=1;
39                 dfs_w(x+1);
40                 vis[x][i]=0;
41             }
42         }
43     }
44 }
45 void dfs_b(int x)
46 {
47     if(x==n+1)
48     {
49         dfs_w(1);//当放完黑皇后开始放白皇后 
50         return ;
51     }
52     else
53     {
54         for(int i=1;i<=n;++i)
55         {
56            if(q_in(x,i,qb)==true)
57            {
58                 qb[x]=i; 
59                 vis[x][i]=1;
60                    dfs_b(x+1);
61                    vis[x][i]=0;
62            }
63         }
64     }
65 }
66 int main()
67 {
68     cin>>n;
69     for(int i=1;i<=n;++i)
70         for(int j=1;j<=n;++j)
71             cin>>map[i][j];
72     dfs_b(1);
73     cout<<ans;
74     return 0;
75 }
76  

 

posted @ 2020-03-26 16:37  caxi  阅读(827)  评论(1编辑  收藏  举报