八皇后---递归
#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(); };