八皇后(eight queens problem)
来源:互联网 发布:创维e780u安装软件 编辑:程序博客网 时间:2024/04/29 15:50
这类问题的求解一般是做连续猜测的的过程。若某种猜测行不通,则撤回,并用另一种猜测代替。这种反向折回并试探新步骤序列的策略称为回溯(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 seatedusing 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 positionint 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;}}elsecout<<"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;elsereturn 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 falsestatic 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;elsereturn 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 wrongbool 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 boardpublic:Board();~Board();void clear();void display()const;void doEightQueens();//initiates the Eight Queens problemint 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;elsereturn false;}elsereturn 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;elsecout<<"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;}
- 八皇后(eight queens problem)
- 八皇后问题,Eight Queens Puzzle
- Eight queens puzzle——八皇后问题
- 递归算法计算八皇后问题(Eight Queen Problem with Recursive Algorithm)
- N-Queens八皇后问题
- eight queens
- eight queens
- N-Queens 八皇后问题I
- “Beginning Python”(二)The eight queens
- eight 皇后
- [LeetCode]N-Queens 八皇后问题扩展(经典深搜)
- 八皇后问题位运算解法(LeetCode #51 N-Queens)
- (codes)eight queens program
- Eight Queens Puzzle
- JAVA Eight Queens
- 【LeetCode】N-Queens && 【九度】题目1140:八皇后
- N-Queens II 八皇后问题的解的个数
- 回溯法——八皇后问题 n-queens
- 漫话中文分词算法(转)
- 路在何方?分析程序员人生之路
- HTTPS和HTTP的区别
- Dell荣获计世资讯“2011用户满意度第一”两项大奖
- 多态
- 八皇后(eight queens problem)
- 持续集成hudson
- Flex4中的自定义事件(转)
- Enterprise Architect 8之数据建模(创建存储过程)
- 一篇不错的讲解Java异常的文章(转载)
- 使用MakeAgent + Source insight搭建跨系统IDE开发平台
- 严蔚敏--线性表的链式表示和实现 代码
- 常用神经网络模型及其应用评述
- WinForms 控件 > 通用概念 > 概念 > 数据绑定 > 绑定控件到在运行时被创建的数据(2011.10.18更新)