八皇后问题
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
非递归求解八皇后(栈来实现) 求出一组解
#include<stdio.h>
int col[8]={0};//列的存储
int left[15]={0};//左斜线的存储
int right[15]={0};//右斜线的存储
int Q[8];//下标代表行数 数值代表皇后所在的列数 以栈存储
void Queen()
{
int top=-1;
int i=0;
int j;
while(top!=7)//栈的存储存八个皇后就跳出
{
//每一行确定后 遍历这一行的每一列
for(;j<8;j++)
{
if(!col[j]&&!left[i+j]&&!right[7+i-j])//列,左右斜线都没有皇后时
{
//放皇后
Q[++top]=j;
col[j]=left[i+j]=right[7+i-j]=1;
i++;
j=0;//i++跳到第二行又从j=0开始遍历
break;
}
}
//当前行不可放皇后 说明前一行没有放好
if(j==8)
{
i--;//回溯到前一行
//抹皇后
j=Q[top--];
col[j]=left[i+j]=right[7+i-j]=0;
j++;//从抹掉的皇后以当前行为基础 从当前列之后遍历
}
}
}
int main(void)
{
int i;
Queen();
for(i=0;i<8;i++)
{
printf("%d",i);
printf(" ");
printf("%d\n",Q[i]);
}
}
非递归求解八皇后(栈来实现) 求出全部解
#include<stdio.h> int col[8]={0};//列的存储 int left[15]={0};//左斜线的存储 int right[15]={0};//右斜线的存储 int Q[8]; int cnt=0;//下标代表行数 数值代表皇后所在的列数 以栈存储 void print() { int i,j; printf("\n\n"); printf("第%d组解:\n",++cnt); for(i=0;i<8;i++) { for(j=0;j<8;j++) { if(Q[i]==j) printf("Q"); else printf("X"); } printf("\n"); } } void Queen() { int top=-1; int i,j; i=j=0; while(1) { while(top!=7)//栈的存储存八个皇后就跳出 { for(;j<8;j++) { //每一行确定后 遍历这一行的每一列 if(!col[j]&&!left[i+j]&&!right[7+i-j])//列,左右斜线都没有皇后时 { //放皇后 Q[++top]=j; col[j]=left[i+j]=right[7+i-j]=1; i++; j=0;//i++跳到第二行又从j=0开始遍历 break; } } //当前行不可放皇后 说明前一行没有放好 if(i>0&&j==8) { i--;//回溯到前一行 //抹皇后 j=Q[top--]; col[j]=left[i+j]=right[7+i-j]=0; j++;//从抹掉的皇后以当前行为基础 从当前列之后遍历 } } if(!i&&!(j-8)) break;//直到回溯到最后一个为止 print(); i--; j=Q[top--]; col[j]=left[i+j]=right[7+i-j]=0; j++; } } int main(void) { Queen(); }
递归求解八皇后 求出全部解
#include<stdio.h> int col[8]={0};//列的存储 int left[15]={0};//左斜线的存储 int right[15]={0};//右斜线的存储 int Q[8]; int cnt=0;//下标代表行数 数值代表皇后所在的列数 以栈存储 void print();//函数调用里面再调用函数需要提前声明 void Queen(int i) { int j; for(j=0;j<8;j++) { if(!col[j]&&!left[i+j]&&!right[7+i-j])//判断是否能放皇后 { Q[i]=j; col[j]=left[i+j]=right[7+i-j]=1; if(i<7) { Queen(i+1); } else { print(); } col[j]=left[i+j]=right[7+i-j]=0;//情况一:i<7但是不能放皇后 情况二:i=7证明8个皇后已经放完需要重新求解 } } } void print() { int i,j; printf("\n\n"); printf("第%d组解:\n",++cnt); for(i=0;i<8;i++) { for(j=0;j<8;j++) { if(Q[i]==j) printf("Q"); else printf("X"); } printf("\n"); } } int main(void) { int i=0; Queen(i); }