您的位置:首页 > 其它

八皇后(回溯经典)

2013-11-04 14:09 99 查看
在8 * 8的棋盘上,摆放8个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上,问共有多少种摆法,并且用程序输出这些摆法。

八皇后作为回溯法的经典例题还是值得一做的,这道题基本可以分成以下步骤:

1.初始化棋盘,0代表没有皇后,1代表有皇后。

2.剪枝函数(判断同一行、同一列或同一斜线上是否有皇后)

3.回溯主程序

4.打印棋盘

程序如下:

#include "stdafx.h"
#include <stdlib.h>
const int Max = 8;
const int chessMen = 1;
int count = 0;
//初始化棋盘
int chessboard[Max][Max] = {0};
//打印棋盘
void Print()
{
for(int i = 0;i< Max;i++)
{
for(int j = 0; j < Max;j++)
{
printf("%d",chessboard[i][j]);
if(j == 7)
{
printf("\n");
}
}
}
}
//剪枝函数
int Cut(int r,int c)
{
//判断同列不同行的格子里有没有皇后
for(int i = 0; i < Max; i++)
if(chessboard[i][c] == chessMen)
return 0;
//判断同行不同列的格子里有没有皇后
for(int j = 0; j < Max; j++)
if(chessboard[r][j] == chessMen)
return 0;
//判断右下角斜线位置有没有皇后
for(int i = r + 1,j = c + 1;i < Max&&j < Max;i++,j++)
if(chessboard[i][j] == chessMen)
return 0;
//判断左下角斜线位置有没有皇后
for(int i = r + 1,j = c - 1;i < Max&&j >= 0;i++,j--)
if(chessboard[i][j] == chessMen)
return 0;
return 1;
}
//回溯主程序
void BackTrack(int num,int queen)
{
if(num <=0 ||queen == Max)
{
if(queen == Max)
{
Print();
count++;
printf("\n");
}
}
else
{
int r = num / Max;
int c = num % Max;
//核心中的核心
if(Cut(r,c))
{
chessboard[r][c] = chessMen;
BackTrack(num - 1,queen + 1);
chessboard[r][c] = 0;
}
BackTrack(num - 1,queen);
}
}
int _tmain(int argc, _TCHAR* argv[])
{

BackTrack(Max * Max - 1,0);
printf("在%d * %d的棋盘中,%d皇后共有%d中摆法",Max,Max,Max,count);
system("Pause");
return 0;
}


最后回溯计算出只有88种,但是据说图论有92种。。这个我是没有找到还能优化的地方了...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: