问题描述:在一个8*8的棋盘上放置8个皇后,不允许任何两个皇后在棋盘的同一行、同一列和同一对角线上。
不重复的方案是12个,其中一个是对称图形,最终结果是11*8+1*4=92。
方法:
经观察发现,对8 x 8的二维数组上的某点a[i][j](0<=i,j<=7)
其主对角线(即左上至右下)上的每个点的i-j+7的值(范围在(0,14))均相等;
其从对角线(即右上至左下)上的每个点的i+j的值(范围在(0,14))均相等;
且每个主对角线之间的i-j+7的值均不同,每个从对角线之间的i-j+7的值亦不同;
如a[3][4]:
主:3-4+7=6
从:3+4=7
因此可设两个数组b[15],c[15]分别表示主、从对角线是否安全
(为1表示有皇后,不安全;为0表示安全)
#include <iostream>
using namespace std;
int data[8][8];
int a[8];//列
int b[15];//主对角线
int c[15];//从对角线
int count = 0;
void eightQueens(int);
void output(const int[][8],int);
int main()
{
int i,j;
for(int i=0;i<15;++i)
b[i]=c[i]=0;//0表示可以放置棋子
for(int i =0;i<8;++i){
a[i] = 0;//i列安全
for(int j =0;j<8;++j)
data[i][j] = 0;
}
eightQueens(0);
cout <<“\ncount = “<<count<<endl;
return 0;
}
void eightQueens(int line){
if(line == 8){
output(data,8);
cout <<endl;
return;
}
for(int column = 0;column <8;++column){
if(a[column] == 0&&b[line-column+7]==0&&c[line+column]==0){//安全
data[line][column] = 1;//放置
a[column] = 1;//这列被占
b[line-column+7] = 1;//主对角线被占
c[line+column] =1;//从对角线被占
eightQueens(line+1);
//重置(回溯)
data[line][column] = 0;
a[column] = 0;
b[line-column+7]=0;
c[line+column] =0;
}
}
}
//输出
void output(const int[][8],int size){
for(int i =0;i<size;++i){
for(int j =0;j<size;++j){
cout<<data[i][j]<<” “;
}
cout <<endl;
}
++count;
}
//转自:http://blog.csdn.net/njnu_mjn/article/details/5449098