八皇后问题(回溯)

/**
 * 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);
}

你可能感兴趣的:(八皇后问题(回溯))