八皇后问题(递归+回溯)

问题描述:在一个8*8的棋盘上放置8个皇后,不允许任何两个皇后在棋盘的同一行、同一列和同一对角线上。

不重复的方案是12个,其中一个是对称图形,最终结果是11*8+1*4=92。

方法:

经观察发现,对8 x 8的二维数组上的某点a[i][j](0<=i,j<=7)
其主对角线(即左上至右下)上的每个点的i-j+7的值(范围在(0,14))均相等;
其从对角线(即右上至左下)上的每个点的i+j的值(范围在(0,14))均相等;
且每个主对角线之间的i-j+7的值均不同,每个从对角线之间的i-j+7的值亦不同;

a[3][4]:
主:3-4+7=6
从:3+4=7

因此可设两个数组b[15],c[15]分别表示主、从对角线是否安全
(为1表示有皇后,不安全;为0表示安全)

#include <iostream>

using namespace std;
int data[8][8];
int a[8];//列
int b[15];//主对角线
int c[15];//从对角线
int count = 0;

void eightQueens(int);
void output(const int[][8],int);
int main()
{
    int i,j;
    for(int i=0;i<15;++i)
        b[i]=c[i]=0;//0表示可以放置棋子
    for(int i =0;i<8;++i){
        a[i] = 0;//i列安全
        for(int j =0;j<8;++j)
            data[i][j] = 0;
    }

    eightQueens(0);
    cout <<“\ncount = “<<count<<endl;

    return 0;
}

void eightQueens(int line){
    if(line == 8){
        output(data,8);
        cout <<endl;
        return;
    }

    for(int column = 0;column <8;++column){
        if(a[column] == 0&&b[line-column+7]==0&&c[line+column]==0){//安全
            data[line][column] = 1;//放置
            a[column] = 1;//这列被占
            b[line-column+7] = 1;//主对角线被占
            c[line+column] =1;//从对角线被占
            eightQueens(line+1);
            //重置(回溯)
            data[line][column] = 0;
            a[column] = 0;
            b[line-column+7]=0;
            c[line+column] =0;
        }
    }
}

//输出
void output(const int[][8],int size){
    for(int i =0;i<size;++i){
        for(int j =0;j<size;++j){
            cout<<data[i][j]<<” “;
        }
        cout <<endl;
    }
    ++count;
}


//转自:http://blog.csdn.net/njnu_mjn/article/details/5449098

    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/u013994536/article/details/50663476
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞