南京理工大学紫金学院VC++课程设计报告
课 程: VC++课程设计 系 别: 计算机系 班 级: 学 号: 姓 名:
选题名称: 八皇后问题 选题难易别: B级
起止时间: 2011.11.21~2011.12.22 指导教师: 朱 俊
2011年 12 月
1. 程序功能介绍
答:这个程序是用于解决八皇后问题的。八皇后问题等于要求八个皇后中的任意两个不能被放在同一行或同一列或同一斜线上。做这个课题,重要的就是先搞清楚哪个位置是合法的放皇后的位置,哪个不能,要先判断,后放置。我的程序进入时会让使用者选择程序的功能,选【1】将会通过使用者自己手动输入第一个皇后的坐标后获得答案;选【2】将会让程序自动运算出固定每一个皇后后所有的排列结果。
2. 课程设计要求
答:(1)增加函数,完成每输入一组解,暂停屏幕,显示“按任意键继续!”。
(2)完善程序,编程计算八皇后问题共有集中排列方案。 (3)增加输入,显示在第一个皇后确定后,共有几组排列。
(4)将每组解的期盼横向排列输出在屏幕上,将五个棋盘并排排列,即一次8行同时输出5个棋盘,同样完成一组解后屏幕暂停,按任意键继续。
(5)求出在什么位置固定一个皇后后,解的数量最多,在什么位置固定皇后后,解的数量最少,最多的解是多少,最少的解是多少,并将最多,最少解的皇后位置及所有的解求出,同样5个一组显示。
3. 对课程题目的分析与注释
答:众所周知的八皇后问题是一个非常古老的问题,问题要求在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击。按照国际象棋的规则,一个皇后可以攻击与之处在同一行或同一列或同一斜线上的其他任何棋子。因此,本课程设计的目的也是通过用C++语言平台在一个8*8的棋盘上放上8个皇后,使得每一个皇后既攻击不到另外七个皇后,也不被另外七个皇后所攻击的92种结构予以实现。使用递归方法最终将其问题变得一目了然,更加易懂。首先要用到类,将程序合理化:我编辑了一个盘棋8*8的类:class Board,还有个回溯法的类:class Stack,关键的类好了,然后编辑好类的成员,然后编辑主函数利用好这些类的成员,让其运算出结果。
4. 程序设计和说明(说明算法思想、设计思路,给出重要的、关键的代码)
答:算法思想:
关键代码: class Stack{ private:
SType data[SSize]; int Top; public:
Stack(){Top=0;} ~Stack(){}
bool isEmpty(){return!Top;} int Size(){return Top;}
bool Push(SType); //处理压栈 bool Pop(SType&); //处理出栈
bool StackTop(SType&); //处理复制栈顶的数据 };
bool Stack::Push(SType d) //将整数d压栈,栈顶加1 { if(Top==SSize) //栈内数据已满,操作不成功 return false; else
{data[Top]=d; Top++;
return true; } }
bool Stack::Pop(SType&d) //将整数d出栈 {if(!Top) //栈中没有数据,操作不成功 return false; else
{Top--; //先动栈顶,再出数据 d=data[Top]; return true; } }
bool Stack::StackTop(SType&d) //复制栈顶的数据到d {if(!Top)
return false; else
{d=data[Top-1]; return true; } }
enum States{used,free};
class Board //一盘棋8*8 {private:
States Rows[8],DiagsLR[15],DiagsRL[15]; //行,左右斜线 public:
char board[8][8]; Board(); ~Board(){}
bool isAttacked(int,int); void Print();
void PlaceQueen(int,int); void RemoveQueen(int,int); };
Board::Board() //构造函数,初始化为空 {
for(int i=0;i<8;i++) {Rows[i]=free;
for(int j=0;j<8;j++) board[i][j]='.'; }
for(int k=0;k<15;k++) DiagsLR[k]=DiagsRL[k]=free; }
void Board::Print() //显示一组排列结果 {
cout< for(int i=0;i<8;i++) { for(int j=0;j<8;j++) cout< bool Board::isAttacked(int row,int col) //判断是否冲突,是返回TRUE,否则返回FALSE { int diagLR=col-row+7; //该皇后的右倾斜线的所有位置 int diagRL=row+col; //该皇后的左倾斜线的所有位置 if(Rows[row]==used || DiagsLR[diagLR]==used || DiagsRL[diagRL]==used) return true; return false; } void Board::PlaceQueen(int row,int col) //放皇后 { int diagLR=col-row+7; //右倾斜线 int diagRL=row+col; //左倾斜线 board[row][col]='Q'; Rows[row]=used; //该行不能再放置 DiagsLR[diagLR]=used; //左倾斜线上不能再放置 DiagsRL[diagRL]=used; //右倾斜线上不能再放置 } void Board::RemoveQueen(int row,int col) //移去皇后 { int diagLR=col-row+7; int diagRL=row+col; board[row][col]='.'; Rows[row]=free; DiagsLR[diagLR]=free; DiagsRL[diagRL]=free; } int comp(char a[8][8],char b[8][8]) //定义比较函数 { for(int i=0;i<8;i++) for(int j=0;j<8;j++) if (a[i][j]!=b[i][j]) return 1; return 0; } //*******************************主函数开始************************************ int main(void) { do {