1
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
思路
建立一个二维数组,将所有值初始化为0,皇后所放的位置修改为2,皇后的同行同列,同一斜线的元素修改为1。
代码如下
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int Queen[8][8];
void printqueen()
//用于打印满足八皇后条件的数组
{
int i,j;
for(i=0; i<8; i++)
{
for( j=0; j<8; j++)
{
printf("%d",Queen[i][j]);
}
printf("\n");
}
printf("\n\n");
}
void f(int a,int b)
//用于将与皇后同一行,同一列,同一斜线的元素进行标记
{
int i;
for(i=0; i<8; i++)
{
if(i!=b)
Queen[a][i]=1;
}
for(i=0; i<8; i++)
{
if(i!=a)
Queen[i][b]=1;
}
for(i=1; a+i<8&&b+i<8; i++)
{
Queen[a+i][b+i]=1;
}
for(i=1; a-i>=0&&b-i>=0; i++)
{
Queen[a-i][b-i]=1;
}
for(i=1; a-i>=0&&b+i<8; i++)
{
Queen[a-i][b+i]=1;
}
for(i=1; a+i<8&&b-i>=0; i++)
{
Queen[a+i][b-i]=1;
}
}
int main()
{
int r0,r1,r2,r3,r4,r5,r6,r7,i,j;
int coun=0;
for(r0=0; r0<8; r0++)
{
for(r1=0; r1<8; r1++)
{
for(r2=0; r2<8; r2++)
{
for(r3=0; r3<8; r3++)
{
for(r4=0; r4<8; r4++)
{
for(r5=0; r5<8; r5++)
{
for(r6=0; r6<8; r6++)
{
for(r7=0; r7<8; r7++)
{
for(i=0; i<8; i++)
for(j=0; j<8; j++)
Queen[i][j]=0;
//对数组进行初始化
Queen[0][r0]=2;
//第一行位置都可放皇后
f(0,r0);
//将第一个皇后所在的行列斜线进行标记
if(Queen[1][r1]==0
//将第一个皇后所在的行列斜线进行标有位置满足与第一个皇后不在同一行,列,斜线,将此处放置第二个皇后,以下分析类似
Queen[1][r1]=2;
f(1,r1);
if(Queen[2][r2]==0)
{
Queen[2][r2]=2;
f(2,r2);
if(Queen[3][r3]==0)
{
Queen[3][r3]=2;
f(3,r3);
if(Queen[4][r4]==0)
{
Queen[4][r4]=2;
f(4,r4);
if(Queen[5][r5]==0)
{
Queen[5][r5]=2;
f(5,r5);
if(Queen[6][r6]==0)
{
Queen[6][r6]=2;
f(6,r6);
if(Queen[7][r7]==0)
{
Queen[7][r7]=2;
f(7,r7);
coun++;
printf("%d\n",coun);
printqueen();
//打印满足八皇后条件的数组
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
return 0;
}
输出结果
共92个结果,举最后一个例子:
92
11111112
11121111
21111111
11211111
11111211
12111111
11111121
11112111