回溯法解决n皇后布局问题
将n个皇后的布局使用一维数组表示,数组的下标为列(COL)数组的元素的值为对应的行(ROW)
主要注意三个地方:
1)判断条件(不同行,不同列,不同对角线)
2)停止条件(回退到第一列最后一个位置)
3)回退标志,每次进行回退操作时,要将回退标志置位。(这个标志位的理解很重要)
代码可以直接运行,产生92个打印的结果。
#include <stdio.h>
#define ROW (8 - 1)
#define COL (8 - 1)
#define true 1
#define false 0
bool isSameLine(int x1,int y1,int x2,int y2)
{
if(x1 == x2)return true;
if(y1 == y2)return true;
return false;
}
int abs(int value)
{
if(value < 0)return -value;
else return value;
}
bool isSameCross(int x1,int y1,int x2,int y2)
{
if(abs(x2 - x1) == abs(y2 - y1))
return true;
return false;
}
char isFit(char array[],int num)
{
for(int i = 0; i <= num; i++)
{
for(int j = i+1; j <= num; j++)
{
if(isSameLine(i,array[i],j,array[j]))
{
return false;
}
if(isSameCross(i,array[i],j,array[j]))
{
return false;
}
}
}
return true;
}
void print_result(char *ar)
{
static int count = 1;
printf("%d)--------------------\n",count++);
for(int i =0; i <= COL;i++)
{
for(int j =0; j <= ROW;j++)
{
if(ar[j] == i) printf("* ");
else printf("- ");
}
printf("\n");
}
printf("-----------------------\n");
//getchar();
}
void work( ){
char ay[8] = {0};
int curCol = 0;
bool isBack = 0;
while(true)
{
if(isBack){
if(curCol == 0 && ay[curCol] == ROW){
//结束条件
break;
}
if(ay[curCol] == ROW){
ay[curCol] = 0;
curCol--;
continue;
}else ay[curCol]++;
isBack = false;
}
if(isFit(ay,curCol)){
//如果满足条件
if(curCol == COL){
//最后一列都满足,直接可以输出
print_result(ay);
//最后一列还没结束,继续
if(ay[curCol] < ROW){
ay[curCol]++;
continue;
}else{
ay[curCol]=0;
curCol--;
//回退,注意设置标志
isBack = true;;
}
}else {
curCol++;
continue;
}
}
//
if(ay[curCol] < ROW){
ay[curCol]++;
}else{
if(curCol == COL){
ay[curCol]=0;
curCol--;
isBack = true;;
}
else curCol++;
}
}
}
int main(int argc, _TCHAR* argv[])
{
work();
getchar();
return 0;
}
//关于递归加回溯法解决此问题的例子,请看http://blog.csdn.net/sandyzhs/article/details/3390022 。这里写的真不错。高手!