/**
* function:八皇后问题。每一行、每一列以及对角线不能有两个皇后。(回溯)
* author:顾博君
* time:2013-1-26
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define MAXN 20
int n,m,good;
int col[MAXN+1],a[MAXN+1],b[2*MAXN+1],c[2*MAXN+1];//标记变量
//打印函数
void print(){
int i,j;
printf("列\t行\n");
for(j=1;j<=n;j++)
printf("%3d\t%d\n",j,col[j]);
fflush(stdin);
for(i=0;i<n;i++)
printf("--");
printf("\n");
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(col[i]==j)
printf("%2d",1);
else
printf("%2d",0);
}
printf("\n");
}
scanf("%*c");//暂停
system("cls");//清屏
}
int main(){
int j;
int count=0;
printf("Enter n:");
scanf("%d",&n);//输入n
for(j=0;j<=n;j++)a[j]=1;//标记变量初始化
for(j=0;j<=2*n;j++)b[j]=c[j]=1;//标记变量初始化
m=1;//第一个皇后
col[1]=1;//皇后的位置是(1,1)
good=1;
col[0]=0;
do{
if(good){
if(m==n){
count++;
printf("%d:\n",count);
print();//打印结果
while(col[m]==n){//如果最后一个皇后已经到了棋盘最后的位置
m--;//回退一行
a[col[m]]=b[m+col[m]]=c[n+m-col[m]]=1;//记录为未被访问
}
col[m]++;//向后移动一列
}
else{
//a表示列'|',b表示'/'对角线,c表示'\'对角线
a[col[m]]=b[m+col[m]]=c[n+m-col[m]]=0;//标记变量记录列和对角线被访问
col[++m]=1;//从下一行的第一个位置开始试探
}
}
else{
while(col[m]==n){//如果已经到了最后一列
m--;//回退一行
a[col[m]]=b[m+col[m]]=c[n+m-col[m]]=1;//记录为未被访问
}
col[m]++;//向后移动一列
}
//最后一行始终未被标记
good=a[col[m]]&&b[m+col[m]]&&c[n+m-col[m]];//检查是否有冲突的皇后
}while(m!=0);
}