八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<windows.h>
#define ms(x,y) memset(x,y,sizeof(x))
const int MAXN=1000+10;
const int INF=1<<30;
using namespace std;
int vis[MAXN][MAXN];
int c[60]; //c[i] 表示第i行的皇后所在的列号
int cnt;
/* -------------------------------------------------------------- */
void eight_queen(int cur, int n) //递归1
{
int i, j, ok;
if(cur == n) {
cnt++;
/*
for(i=0; i<n; i++){
for(j=0; j<n; j++){
if(j == c[i]) printf("# ");
else printf(". ");
}
printf("\n");
}
printf("\n%d\n\n", cnt);
*/
return;
}
for(i=0; i<n; i++){
c[cur] = i;
ok=1;
for(j=0; j<cur; j++){
if(i == c[j] || cur - i == j - c[j] || cur + i == j + c[j]){
ok=0;
break;
}
}
if(ok) eight_queen(cur+1, n);
}
}
/* -------------------------------------------------------------- */
void eight_queen1(int cur, int n) //递归2
{
int i, j;
if(cur == n){
cnt++;
/*
for(i=0; i<n; i++){
for(j=0; j<n; j++){
if(j == c[i]) printf("# ");
else printf(". ");
}
printf("\n");
}
printf("\n%d\n\n", cnt);
*/
return;
}
for(i=0; i<n; i++){
c[cur] = i;
if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]){
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
eight_queen1(cur+1, n);
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;
}
}
}
/* -------------------------------------------------------------- */
bool Judge(int r, int c, int n) //迭代
{
if(!vis[0][c] && !vis[1][r + c] && !vis[2][r - c + n]){
vis[0][c] = vis[1][r + c] = vis[2][r - c + n] = 1;
return 1;
}
return 0;
}
void SetZero(int r, int c, int n)
{
vis[0][c] = vis[1][r + c] = vis[2][r - c + n] = 0;
}
void eight_queen2(int cur, int n)
{
int i, j, C, R;
c[cur] = -1;
while(cur >= 0)
{
c[cur]++;
while(c[cur] < n && !Judge(cur, c[cur], n)) //在该行寻找适合的列
c[cur]++;
if(c[cur] < n){
if(cur == n - 1){
cnt++;
/*
for(i=0; i<n; i++){
for(j=0; j<n; j++){
if(j == c[i]) printf("# ");
else printf(". ");
}
printf("\n");
}
printf("\n%d\n\n", cnt);
*/
SetZero(cur, c[cur], n);
}
else{ //处理下一行皇后
cur++;
c[cur] = -1;
}
}
else{ //回溯
cur--;
SetZero(cur, c[cur], n);
}
}
}
/* -------------------------------------------------------------- */
int main()
{
int n = 13;
FILETIME beg,end;
GetSystemTimeAsFileTime(&beg);
eight_queen2(0, n);
GetSystemTimeAsFileTime(&end);
int dur = 100*(end.dwLowDateTime-beg.dwLowDateTime);
printf("%d\n", dur);
printf("%d\n", cnt);
return 0;
}