N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5382 Accepted Submission(s): 2454
你的任务是,对于给定的N,求出有多少种合法的放置方法。
经典dfs
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
int ch[25][25]; // 棋盘
int n, num, result[25];
void dfs(int x, int y)
{
if(ch[x][y]) return; //如果该点已经被攻击,则返回
int i, xx, yy;
if(x == n) //如果
{
num++;
return;
}
//下面个人觉得比较巧妙,因为会有重复的地方很难分析是属于哪个皇后
//若用了下面位置的 ++ or -- ,则巧妙地避免上述情况
//一共八个方向进行标记:上、下、左、右、左上、左下、右上、右下
xx = x; yy = y;
while(xx>0) ch[xx--][y]++;
xx = x; yy = y;
while(yy>0) ch[x][yy--]++;
xx = x; yy = y;
while(xx<=n) ch[xx++][y]++;
xx = x; yy = y;
while(yy<=n) ch[x][yy++]++;
xx = x; yy = y;
while(xx<=n && yy<=n) ch[xx++][yy++]++;
xx = x; yy = y;
while(xx>0 && yy<=n) ch[xx--][yy++]++;
xx = x; yy = y;
while(xx<=n && yy>0) ch[xx++][yy--]++;
xx = x; yy = y;
while(xx>0 && yy>0) ch[xx--][yy--]++;
for(i = 1; i <= n; i++)
{
dfs(x+1, i);
}
//若这个皇后深搜后的结果不成功,则要返回原来的情况,八个方向都 --
xx = x; yy = y;
while(xx>0) ch[xx--][y]--;
xx = x; yy = y;
while(yy>0) ch[x][yy--]--;
xx = x; yy = y;
while(xx<=n) ch[xx++][y]--;
xx = x; yy = y;
while(yy<=n) ch[x][yy++]--;
xx = x; yy = y;
while(xx<=n && yy<=n) ch[xx++][yy++]--;
xx = x; yy = y;
while(xx>0 && yy<=n) ch[xx--][yy++]--;
xx = x; yy = y;
while(xx<=n && yy>0) ch[xx++][yy--]--;
xx = x; yy = y;
while(xx>0 && yy>0) ch[xx--][yy--]--;
}
void init() //初始化函数
{
int i, j;
for(i = 0; i < 12; i++)
for(j = 0; j < 12; j++)
ch[i][j] = 0;
}
void set()
{
int i, k;
init();
for(k = 1; k <= 10; k++)
{
num = 0;
n = k; //初始化
for(i = 1; i <= k; i++)
{
//初始化
dfs(1, i); //继续dfs寻找
}
result[k] = num;
}
}
int main()
{
set();
while(scanf("%d", &n), n)
{
int a=result[n];
printf("%d\n", a);
}
return 0;
}