N皇后问题

Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。

Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
SampleInput
1
8
5
0
SampleOutput
1
92
10
 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 int map[20][20];     //棋盘
 6 int ans[20]={0},num,n;  //n为输入的数,num为结果,ans[n]存储结果
 7 
 8 void dfs(int x,int y)
 9 {
10     if(map[x][y])  //如果标记不是0的话,证明不可放,回朔到上一种情况
11         return;
12     int i,xx,yy;
13     if(x==n)        //如果已经放好n个棋子,证明这是一个可行解,可行解个数加一,回朔到上一种情况
14     {
15         num++;
16         return;
17     }
18     //对8个方向进行搜索,把(x,y)所在横排,竖排,斜排上面的元素全部标记为非0
19     xx=x;yy=y;
20     while(xx>0) map[xx--][yy]++;  //
21     xx=x;yy=y;
22     while(yy>0) map[xx][yy--]++;  //
23     xx=x;yy=y;
24     while(xx<=n) map[xx++][yy]++;  //
25     xx=x;yy=y;
26     while(yy<=n) map[xx][yy++]++;  //
27     xx=x;yy=y;
28     while(xx<=n&&yy<=n) map[xx++][yy++]++;  //右上
29     xx=x;yy=y;
30     while(xx<=n&&yy>0) map[xx++][yy--]++;   //右下
31     xx=x;yy=y;
32     while(xx>0&&yy<=n) map[xx--][yy++]++;   //左上
33     xx=x;yy=y;
34     while(xx>0&&yy>0) map[xx--][yy--]++;   //左下
35 
36     for(i=1;i<=n;i++)     
37     {
38         dfs(x+1,i);    //棋子序号加一,棋子横坐标变为x+1(因为当x处有棋子时,横坐标为x都标记为非0)
39                             //然后依次增加纵坐标y,找到一个标记位为0的位置(如果非0则返回,继续查找)
40                             //如果找到了,则继续重复这一步。
41     }                    
42 
43     //如果没找到,则恢复原样[把由(1,1)推出的map[][]上的标记恢复)
44     //并返回到set();中,继续执行set();中的j层循环,把初始值设为(1,2)[2即为j+1],重复执行上述步骤。    
45     xx=x;yy=y;
46     while(xx>0) map[xx--][yy]--;
47     xx=x;yy=y;
48     while(yy>0) map[xx][yy--]--;
49     xx=x;yy=y;
50     while(xx<=n) map[xx++][yy]--;
51     xx=x;yy=y;
52     while(yy<=n) map[xx][yy++]--;
53     xx=x;yy=y;
54     while(xx<=n&&yy<=n) map[xx++][yy++]--;
55     xx=x;yy=y;
56     while(xx<=n&&yy>0) map[xx++][yy--]--;
57     xx=x;yy=y;
58     while(xx>0&&yy<=n) map[xx--][yy++]--;
59     xx=x;yy=y;
60     while(xx>0&&yy>0) map[xx--][yy--]--;
61 }
62 
63 void set()  //分别找到n为1到10的所有结果,并存到ans[i]中
64 {
65     int i,j;
66     for(i=1;i<=10;i++)
67     {
68         num=0;n=i;
69         for(j=1;j<=i;j++)
70         {
71             memset(map,0,sizeof(map));
72             dfs(1,j);      //增加初始棋子的y坐标
73         }
74         ans[i]=num;
75     }
76 }
77 
78 
79 int main(){
80     int t;
81     set();
82     while(cin>>n,n)
83     {
84       cout<<ans[n]<<endl;
85     }
86 
87     return 0;
88 }
View Code

遍历过程:

x轴↓                                                                  y轴→

原文地址:https://www.cnblogs.com/to-creat/p/5003285.html