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