【DFS+回溯】N皇后问题

描述

  在 N*N 的棋盘上放置 N 个皇后而彼此不受攻击(即在棋盘的任一行,任一列和任一对角线上 不能放置 2 个皇后),编程求解所有的

摆放方法。

输入

  一个数字N (3 <= N <= 10) 表示棋盘是N * N大小的。

输出

  输出方案数;若无方案,则输出 "no solute!"

输入样例 1 

4

输出样例 1

 
   
2

解题思路
  这是一道回溯搜索的经典题目。首先,我们每放一个皇后都给列打上标记(因为我们是一行一行的放皇后,所以保证行的唯一性),
我们发现,每个皇后控制两个对角线,然后每一条对角线都满足这样一个特点:要么横坐标加纵坐标相等,要么横坐标减纵坐标相等。所
以就开两个数组判断。
题解
 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 bool mp[10001][10001];//地图(方便输出)
 8 void queen(int ans)
 9 {
10     if(ans==n+1)//如果八个皇后放完了就方案加一
11     {
12         num++;
13         
14         return;
15     }
16     for(int j=1;j<=n;j++)
17     {
18         if(!l[j]&&!x[ans-j]&&!y[ans+j])//如果这个皇后放了没有冲突
19         {
20             l[j]=true;
21             x[ans-j]=true;
22             y[ans+j]=true;
23             mp[ans][j]=true;//打标记
24             queen(ans+1);//放下一个皇后
25             l[j]=false;
26             x[ans-j]=false;
27             y[ans+j]=false;
28             mp[ans][j]=false;//取消标记(回溯)
29         }
30     }
31     return;
32 }
33 int main()
34 {
35     cin>>n;
36     queen(1);
37     cout<<num;
38     return 0;
39 }
 

猜你喜欢

转载自www.cnblogs.com/hualian/p/11031988.html