八皇后问题所有解枚举
#include "stdafx.h" //int taken[8][8]; // 存储该地方被皇后攻击到, 0--没有攻击到, >0被攻击到 int allstone[8][8]; // 存储该地方是否有皇后,1--代表有皇后,0--代表没有 class NUM_STACK { public: NUM_STACK(){ iTop = -1; } bool push(int iNum) { iTop++; if(iTop >= 8){ iTop--; return false; } _stack[iTop] = iNum; return true; } bool pop(int& iNum) { if(iTop == -1){ return false; } iNum = _stack[iTop]; iTop--; return true; } int get_size() { return iTop+1; } bool get_value(int index, int& iValue) { if(index+1 > get_size()){ return false; } iValue = _stack[index]; return true; } protected: int _stack[8]; int iTop; }; struct NUM_ELEM { int iNum; bool bTake; }; class NUM_ARRAY { public: NUM_ARRAY(){ int ii; for(ii=0;ii<8;ii++){ _array[ii].iNum = ii; _array[ii].bTake = false; } } void take_next_num(int& iNum) { iNum++; while(iNum < 8){ if(!_array[iNum].bTake){ break; } iNum++; } if(iNum >= 8){ iNum = -1; return; } _array[iNum].bTake = true; iNum = _array[iNum].iNum; } void release_num(int iNum) { if(iNum<0 || iNum >= 8){ return; } _array[iNum].bTake = false; } protected: NUM_ELEM _array[8]; }; bool take_pos(int x, int y, bool bTaken = true) { //int ii; //if(bTaken){ // if(allstone[x][y] == 1){ // return false; // } //}else{ // if(allstone[x][y] != 1){ // return false; // } //} //int delta = bTaken ? 1 : -1; //// 行 //for(ii=0;ii<8;ii++){ // taken[x][ii] += delta; //} //// 列 //for(ii=0;ii<8;ii++){ // taken[ii][y] += delta; //} //// 从左到右下移 //int k = (x < y) ? x : y; //for(ii=0;ii<8;ii++){ // if(x-k+ii >= 8 || y-k+ii >= 8){ // break; // } // taken[x-k+ii][y-k+ii] += delta; //} //// 从右到左下移 //k = (7 - x < y) ? 7 - x : y; //for(ii=0;ii<8;ii++){ // if(x+k-ii < 0 || y-k+ii >= 8){ // break; // } // taken[x+k-ii][y-k+ii] += delta; //} if(bTaken){ allstone[x][y] = 1; // 占用 }else{ allstone[x][y] = 0; // 拔起 } return true; } bool check_and_take(int x, int y) { if(allstone[x][y] == 1){ return false; } int ii; // 检查路线上是否有其他皇后 // 检查行 for(ii=0;ii<8;ii++){ if( allstone[x][ii] == 1){ return false; } } // 检查列 for(ii=0;ii<8;ii++){ if( allstone[ii][y] == 1){ return false; } } // 检查从左到右下移 int k = (x < y) ? x : y; for(ii=0;ii<8;ii++){ if(x-k+ii >= 8 || y-k+ii >= 8){ break; } if(allstone[x-k+ii][y-k+ii] == 1){ return false; } } // 检查从右到左下移 k = ( 7 - x < y) ? 7 - x : y; for(ii=0;ii<8;ii++){ if(x+k-ii < 0 || y-k+ii >= 8){ break; } if( allstone[x+k-ii][y-k+ii] == 1){ return false; } } return take_pos(x, y); } int _tmain(int argc, _TCHAR* argv[]) { NUM_ARRAY num_array; NUM_STACK num_stack; int iRow = 0; int iCol = 0; int iIndex = -1; int iAll = 0; //while(iRow>=0 && iRow<8){ while(iRow>=0){ if(iRow >= 8){ iRow--; num_stack.pop(iCol); num_array.release_num(iCol); take_pos(iRow, iCol, false); iIndex = iCol; } num_array.take_next_num(iIndex); iCol = iIndex; while(iCol>=0){ if(check_and_take(iRow, iCol)){ num_stack.push(iCol); iRow++; break; }else{ num_array.release_num(iCol); num_array.take_next_num(iCol); } } if(iCol<0){ if(iRow>0){ iRow--; num_stack.pop(iCol); num_array.release_num(iCol); take_pos(iRow, iCol, false); iIndex = iCol; }else{ // 枚举完成,退出 break; } }else{ if(num_stack.get_size() == 8){ // 找到一组解 int ii; iAll++; printf("%d: ",iAll); for(ii=0;ii<8;ii++){ int iCol; num_stack.get_value(ii, iCol); printf("(%d,%d) ", ii+1, iCol+1); } printf("\r\n\r\n"); }else{ iIndex = -1; } } } if(iAll == 0){ printf("无解\r\n\r\n"); } return 0; }