八皇后---递归

#include<iostream>
#include<vector>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;

int occupy[8][8] = {0}; //8*8棋盘上记录占据的位置
int mylocation[8] = {0};//记录当前正在计算的每行的索引
vector< vector<int> > locations; //记录所以8皇后的解

//8*8棋盘每个位置初始化
void fillOccupy(int occupyBegin[8][8], int value=9)
{
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            occupyBegin[i][j]=value;
        }
    }
}

//打印8*8棋盘的当前布局
void showCur(int occupyBegin[8][8])
{
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            cout<<occupyBegin[i][j]<<"  ";
        }
        cout<<endl;
    }
    cout<<endl;
}

//选定8*8棋盘的一个位置后,将这个位置所影响后续行的位置都进行占据标志设置(取决于用户传value是非0)
//选定8*8棋盘的一个位置后,将这个位置所影响后续行的位置都清除占据标志设置(取决于用户传value是0)
void setOccupy(int occupyBegin[8][8], int curRow, int curColum, int value, int lengthRow, int lengthColumn)
{
    //设置后续行的斜右行
    for(int iRow = curRow; iRow < lengthRow; ++iRow)
    {
        if(curColum+iRow-curRow >= lengthColumn)
        {
            break;
        }
        occupyBegin[iRow][curColum+(iRow-curRow)] = value;
    }

    //设置后续行的斜左行
    for(int iRow = curRow; iRow < lengthRow; ++iRow)
    {
        if(curColum-iRow+curRow < 0)
        {
            break;
        }
        occupyBegin[iRow][curColum-(iRow-curRow)] = value;
    }

    //设置后续行的竖行
    for(int iRow = curRow; iRow < lengthRow; ++iRow)
    {
        occupyBegin[iRow][curColum] = value;
    }

    if(value != 0)
    {
        occupyBegin[curRow][curColum]=1;
    }
}


//测试占据函数 void testSetOccupy() { cout<<endl<<"------00------"<<endl; setOccupy(occupy, 0,0,1,8,8); showCur(occupy); setOccupy(occupy, 0,0,0,8,8); cout<<endl<<"------01------"<<endl; setOccupy(occupy, 0,1,1,8,8); showCur(occupy); setOccupy(occupy, 0,1,0,8,8); cout<<endl<<"------23------"<<endl; setOccupy(occupy, 2,3,1,8,8); showCur(occupy); setOccupy(occupy, 2,3,0,8,8); cout<<endl<<"-----27-------"<<endl; setOccupy(occupy, 2,7,1,8,8); showCur(occupy); setOccupy(occupy, 2,7,0,8,8); cout<<endl<<"------77------"<<endl; setOccupy(occupy, 7,7,1,8,8); showCur(occupy); setOccupy(occupy, 7,7,0,8,8); cout<<endl<<"------clear43-----"<<endl; fillOccupy(occupy); showCur(occupy); cout<<endl<<"*******************"<<endl; setOccupy(occupy, 4,3,0,8,8); showCur(occupy); fillOccupy(occupy,0); } void Calcu(int occupyBegin[8][8], int location[8], int curRow, int lengthRow, int lengthColumn) { //遍历此行的每一个列 for(int i = 0; i < lengthColumn; i++) { //找到列中可用的位置,同时把此位置影响的后面行的格子占据住 if (occupy[curRow][i] == 0) { location[curRow] = i; //location里面记录此行占据的位置 setOccupy(occupyBegin, curRow, i, 9, lengthRow, lengthColumn); //占据影响的后面的格子 if(curRow == lengthRow -1) /*如果有位置占用并且现在行是最后一行,那么vector记录次序,继续在最后一行找下一个位置。 */ { vector<int> value; for(int k = 0; k < lengthColumn; ++k) { value.push_back(location[k]); } locations.push_back(value); int tmp[8][8]={0}; cout<<"find a sequence: "; for(int k = 0; k < lengthColumn; ++k) { cout<<location[k]<< " "; setOccupy(tmp,k,location[k],9,lengthRow, lengthColumn); } cout<<endl; showCur(tmp); } else //不是最后一行的话让下一行开始找 { //递归让下一行继续找位置 Calcu(occupyBegin, location,curRow+1, lengthRow, lengthColumn); } //当前行把当前占据位置影响的格子情况清除掉,然后当前行找下一个可用位置 /*整个占据情况清掉后,把当前行的之前行再重新设置一遍占用*/ fillOccupy(occupyBegin, 0); for(int j = 0; j < curRow; j++) { setOccupy(occupyBegin, j, location[j],9,lengthRow, lengthColumn); } } } } int main(int argc, char** argv) { Calcu(occupy, mylocation, 0, 8, 8); cout<< locations.size()<<endl; //testSetOccupy(); };
原文地址:https://www.cnblogs.com/silentNight/p/13945024.html