N皇后问题
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。,由此演变出N皇后问题:
下面给出N皇后的两种求解方式:
第一种方式:DFS直接搜索
代码:
<span style="font-size:18px;"><strong>#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int x[100],N,sum;
int ans[100];
bool place(int k) //判断第K个皇后是否可以加入
{
for(inti=1; i<k; i++)
{
if(x[i]==x[k] || abs(k-i)==abs(x[k]-x[i]))
return false;
}
returntrue ;
}
void DFS(int k) //k的初始值为1
{
if(k>N) //安排完N个皇后后sum++
{
sum++;
// printf("sum = %d\n", sum);
// for(int i=1; i<=N; i++)
// printf("%d ", x[i]);
// printf("\n");
return ;
}
else
{
for(int i=1; i<=N; i++) //找第K个皇后的列坐标
{
x[k]=i;
if(place(k))
{
//printf("%d ", x[k]);
DFS(k+1);
}
}
}
}
int main()
{
while(scanf("%d",&N)!=EOF && N)
{
if(ans[N])
printf("%d\n",ans[N]);
else
{
DFS(1);
ans[N] = sum;
printf("%d\n", ans[N]);
}
}
return 0;
}</strong></span>第二种方式:没有懂,应该是位运算,不明白设计过程。
<span style="font-size:18px;"><strong>#include <stdio.h>
#include <stdlib.h>
int ans[20];
long sum = 0, upperlim = 1;
void test(long row, long ld, long rd)
{
if (row!= upperlim)
{
longpos = upperlim & ~(row | ld | rd);
while(pos)
{
long p = pos & -pos;
pos -= p;
test(row + p, (ld + p) << 1, (rd + p) >> 1);
}
}
else
sum++;
}
int main()
{
int n ;
for(inti=1; i<=20; i++)
ans[i] = -1;
while(scanf("%d", &n) != EOF, n)
{
if(ans[n] != -1)
printf("%d\n", ans[n]);
else
{
sum = 0;
upperlim = 1;
upperlim = (upperlim << n) - 1;
test(0, 0, 0);
ans[n] = sum;
printf("%d\n", sum);
}
}
return 0;
}</strong></span>原文:http://blog.csdn.net/jdliyao/article/details/51368049