问题描述
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。(摘自百度百科。。。)
枚举法
别的不说了,直接上代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
void print_(int qu[]) //输出显示函数
{
int i, j;
for(i = 0; i < 8; i++){
for(j = 0; j < qu[i]; j++){
printf("%c", 6);
}
printf("%c", 12);
for(j = 0; j < 8-qu[i]-1; j++){
printf("%c", 6);
}
printf("\n");
}
}
bool is(int qu[]) //判断是否会冲突
{
int i, j;
for(i = 0; i < 8; i++)
{
for(j = 0; j < i; j++)
{
if(qu[i] == qu[j]) return false;
if(abs(qu[i]-qu[j]) == abs(i-j)) return false;
}
}
return true;
}
int main()
{
int a[10]={0};
int i, number = 1;
for(a[0] = 0; a[0] < 8; a[0]++) //依次枚举8行。。。
for(a[1] = 0; a[1] < 8; a[1]++)
for(a[2] = 0; a[2] < 8; a[2]++)
for(a[3] = 0; a[3] < 8; a[3]++)
for(a[4] = 0; a[4] < 8; a[4]++)
for(a[5] = 0; a[5] < 8; a[5]++)
for(a[6] = 0; a[6] < 8; a[6]++)
for(a[7] = 0; a[7] < 8; a[7]++)
{
if(is(a)){
printf("Kase %d:\n", number++);
print_(a);
printf("\n");
}
}
return 0;
}
回溯法
#include<cstdio>
#include<cmath>
using namespace std;
void showQueen(int queenArr[], int n, int nSolution) //输出显示函数
{
printf("Case %d:\n", nSolution);
for(int i = 0; i < n; i++){
for(int j = 0; j < queenArr[i]; j++){
printf("%c", 6);
}
printf("%c", 12);
for(int j = 0; j < n - queenArr[i] - 1; j++){
printf("%c", 6);
}
printf("\n");
}
}
bool isClash(int queenArr[], int nRow)
{
for(int iRow = 0; iRow < nRow; iRow++){ ///检测当前第nRow行的摆放是否与其前面第iRow行冲突
if(queenArr[iRow] == queenArr[nRow]){ ///在同一列上,冲突
return true;
}
if(abs(queenArr[iRow]-queenArr[nRow]) == abs(iRow-nRow)){ ///在对角线上,冲突
return true;
}
}
return false;
}
void putQueen(int queenArr[], int nRow, int nLen, int &nSolution) ///已放完前nRow行的皇后,正在放第nRow行的皇后
{
for(int i = 0; i < nLen; i++){
queenArr[nRow] = i; ///把皇后放在第nRow行的第i列
///检查冲突,如果有冲突,忽略从第nRow行开始以下的所有皇后摆放
if(!isClash(queenArr, nRow)){
if(nRow == nLen - 1){ ///全部8行已经摆放完毕,且无冲突
nSolution++;
showQueen(queenArr, nLen, nSolution);
}
else{
putQueen(queenArr, nRow + 1, nLen, nSolution); ///放下一行皇后的位置
}
}
}
}
int main()
{
int queenArr[20];
int nSolution = 0; ///解法数量
putQueen(queenArr, 0, 8, nSolution); ///从第0行开始放,8皇后问题
return 0;
}
但在有些问题中,回溯法常常会产生大量的重复计算,导致TLE,可用动态规划来解决。。。