八皇后(eight queens problem)

这类问题的求解一般是做连续猜测的的过程。若某种猜测行不通,则撤回,并用另一种猜测代替。这种反向折回并试探新步骤序列的策略称为回溯(backtracking)。

八皇后规则的描绘大家应都已熟悉了,这里我就不多说。八皇后问题的解决要用到递归和回溯的方法。下面是我基于数组的尝试:

#include<iostream> #include<cmath> #include<cstdlib> //here using the array arr's index as the col of the queen seated //and using the array arr's values as the row of the queen seated using namespace std; bool placeQueen(int *arr,int row,int size); bool safe(int *arr,int row)// decide whether the queen that will be set is safe in current position int main() { const int MAX=16; int arr[MAX]={0,0,0,0,0,0,0,0}; cout<<"PlaceQueen :"<<endl; int first=0; char table[MAX][MAX];// simulating board; bool success =placeQueen(arr,first,MAX); if(success) { cout<<"place eight queens success !"<<endl; //put the queens on the simulation board; for(int i=0;i<MAX;i++) { for(int j=0;j<MAX;j++) { table[j][i]='O'; } table[arr[i]][i]='*'; cout<<i+1<<" "; } cout<<endl; // display the status that queens how was seted on board; for(int i=0;i<MAX;i++){ for(int j=0;j<MAX;j++) cout<<table[i][j]<<" "; cout<<i+1<<endl; } } else cout<<"place eight queens failed !"<<endl; return 0; } bool safe(int *arr,int row) { if(row==0) return true; else{ int i=0; while((i<row)&&(arr[row]!=arr[i])&&(abs(arr[row]-arr[i])!=abs(row-i))) { i++; } if(i==row) return true; else return false; } } bool placeQueen(int *arr,int row,int size) { if(row>size-1) return true; else { bool isok=false; while(!isok&&arr[row]<size) { if(safe(arr,row)) isok=placeQueen(arr,row+1,size); if(!isok) { arr[row+1]=0; arr[row]++; } } return isok; } }
基于vector的尝试:

这里要用到queen类,其中定义了queen目前所在的位置信息(col and row ),判断是否会受到攻击的函数。另外一个static const 常量用于将queens 限定在一个board上面:

#ifndef QUEEN_H_ #define QUEEN_H_ #include"board.h" class Board; class Queen { private: int row; int col; static const Board *boardPtr; public: Queen(); Queen(int _row,int _col); int getRow()const; int getCol()const; void nextRow(); bool isUnderAttack()const; //Detemines whether the queen is under attack by another //queen .if there is a queen same row or the same diagonal //return true;otherwise return false static void setBoard(const Board *bPtr); //save a pointer to the board for all queens }; #endif #include"queen.h" #include<cmath> #include<cstddef> const Board *Queen::boardPtr=NULL; void Queen::setBoard(const Board *bPtr) { boardPtr=bPtr; } Queen::Queen() { row=col=0; } Queen::Queen(int _row,int _col):row(_row),col(_col) { } int Queen::getRow()const { return row; } int Queen::getCol()const { return col; } void Queen::nextRow() { row++; } bool Queen::isUnderAttack()const { int i=0; while((i<col)&&(boardPtr->getQueen(i)->getRow()!=row)&& (std::abs(boardPtr->getQueen(i)->getCol()-col)!= std::abs(boardPtr->getQueen(i)->getRow()-row))) { i++; } if(i==col) return false; else return true; }
board也用一个类来定义,其实现用的是标准库vector类,vector 的不同索引中存放了不同位置的queen;其主要操作是,尝试一个安全的位置,并放置queen于其上。


#ifndef BOARD_H_ #define BOARD_H_ #include<vector> #include<cassert> #include<cstddef> #include<iostream> #include"queen.h" class Queen; using namespace std; static const int BOARD_SIZE=8; class Board { private: vector<const Queen*> queens;//maybe something wrong bool isQueen(int _row,int _col)const; //determines wherther there is a queen in //position(int _row,int _col) bool placeQueens(Queen *queenPtr); //Attempts to place queens on board starting //with designated queen. void removeQueen(); //remove the last queen on the board, but does not delete //it. void setQueen(const Queen *queenPtr); //Place a queen on the board public: Board(); ~Board(); void clear(); void display()const; void doEightQueens(); //initiates the Eight Queens problem int getNumQueens()const; const Queen * getQueen(int index)const; //return a pointer to the queen at the designated index }; #endif #include"board.h" Board::Board() { queens=vector<const Queen*>(); } Board::~Board() { clear(); } bool Board::isQueen(int _row,int _col)const { if(_row<queens.size()) { if(queens[_row]->getCol()==_col) return true; else return false; } else return false; } bool Board::placeQueens(Queen *queenPtr) { if(queenPtr->getCol()>=BOARD_SIZE) { delete queenPtr; return true; } else { bool success =false; while((!success)&&(queenPtr->getRow()<BOARD_SIZE)) { if(queenPtr->isUnderAttack()) { queenPtr->nextRow(); } else { setQueen(queenPtr); Queen *newQueenPtr=new Queen(0, queenPtr->getCol()+1); assert(newQueenPtr!=NULL); success=placeQueens(newQueenPtr); if(!success) { delete newQueenPtr; removeQueen(); queenPtr->nextRow(); } } } return success; } } void Board::removeQueen() { queens.pop_back(); } void Board::setQueen(const Queen *queenPtr) { queens.push_back(queenPtr); } void Board::clear() { int num=getNumQueens(); for(int i=num-1;i>=0;i--) { delete queens[i]; removeQueen(); } } void Board::doEightQueens() { Queen *qPtr=new Queen(0,0); assert(qPtr!=NULL); bool isok=placeQueens(qPtr); if(isok) cout<<"do eight queens success !"<<endl; else cout<<"do eight queens failed !"<<endl; } int Board::getNumQueens()const { return queens.size(); } void Board::display()const { for(int i=0;i<getNumQueens();i++) { cout<<queens[i]->getCol()<<" " <<queens[i]->getRow()<<endl; } } const Queen * Board::getQueen(int index)const { return queens[index]; }
下面是主函数,用来测试一下

#include"queen.h" #include"board.h" int main() { Board aboard; Queen::setBoard(&aboard); cout<<"lalal"; aboard.doEightQueens(); aboard.display(); return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值