八皇后(内含动态演示)

来源:互联网 发布:js 获取复选框选中的值 编辑:程序博客网 时间:2024/05/17 03:54

// 只用C++完成的一个八皇后问题,以图形的形式展示92种结果,以及算法的具体动态演示

// 具体的一些概念可在实验报告文档中查看解释

一、几个需要提前注意的问题:

1.由于需要利用C++画图,所以我使用EasyX图形函数库。可以在 EasyX下载 处直接下载,然后识别安装自己的编程软件即可使用。

   在使用此图形库时,需包含 #include "graphics.h" 头文件,依次打开后可以查看到EasyX里面函数的使用(或是安装在桌面也可以查看具体函数及使用)。

2.几个函数的说明: 延时函数    需要包含头文件 #include <windows.h> ,函数使用  Sleep(1.2 * 1000);//表示在此时暂停1.2秒

                                 清零数组    memset(k, 0, sizeof k); 清除k数组里的所有 //一维 二维 或是二维的某一行都行

                                 暂停函数    system("pause");  

                                 画布的创建与关闭   initgraph(长, 宽);    closegraph();

                                 图片的插入:IMAGE img1; // 定义 IMAGE1 对象
                                                      loadimage(&img1, "D:\\WSX.jpg",400,250); // 读取图片到 img1 对象中
                                                      putimage(801, 0, &img1); // 在左上角的坐标 (801, 0) 位置显示 IMAGE1 对象


二、核心算法:回溯法的基础代码

void pan(int curr)//验证curr行的放置{if (curr == 8)  //当行数达到边界时,则出现了一个没有冲突符合条件的解{num++; //记录现在满足条件解的个数}else{for (int i = 0; i<8; i++) //循环验证在curr行时,把皇后放置在第i列时{int ok = 1;//标记此行是否放置了皇后memset(k[curr], 0, sizeof k[curr]);//每次重新在此行放置皇后时,清空此行的之前放置的东西k[curr][i] = 1;//标记在curr行i列放置的皇后c[curr] = i;//表示curr行放置皇后的列数for (int j = 0; j<curr; j++)//判断是否与前面的皇后位置有冲突{if (c[curr] == c[j] || curr - c[curr] == j - c[j] || curr + c[curr] == j + c[j]){//判断是否在同一列和是否会在对角线上ok = 0;//如果出现冲突,则将此处的皇后撤掉,表示此行没有放置合适的皇后k[curr][i] = 0;break;//只要出现有冲突的,则跳出判断循环,把此行的皇后放置到下一列}}if (ok)//若是此行已经放置好了合适的皇后{pan(curr + 1);//进行下一行皇后位置的寻找}}}}

只需要在main函数中调用pan(0);函数以及加个自己想要输出的内容函数即可。

  

三、图形动态化

  只需要使用图形函数编辑,在需要的位置加入延时函数即可。

四、具体代码

#define _CRT_SECURE_NO_WARNINGS#include "iostream"#include "string"#include "graphics.h"//其内包含easyx图形函数库#include<conio.h>#include <cstdlib>#include <stdio.h>#include <windows.h>//延时函数头文件using namespace std;int pp = 0;//判断查看怎样的结果,决定了延时位置的不同,则展现结果就不同void z0()//pp=0时,查看算法过程的动态演示{if (pp == 0)  Sleep(0.4 * 1000);  //延时函数,延时0.4秒}void z1()//pp=1时,查看符合要求的92种结果{if (pp == 1) Sleep(1.2 * 1000);}int curr;int c[8] = { 0 };int num = 0;char s[5];int k[8][8];void print(){sprintf(s, "%d", num);//将此时符合条件的解得个数(int)转化格式成为字符串(char s[5])outtextxy(1000, 400, s);//将个数输出在屏幕的(1000,400)的位置}void pan(int curr)//验证curr行的放置{if (curr == 8)  //当行数达到边界时,则出现了一个没有冲突符合条件的解{num++; //记录现在满足条件解的个数print();z1();//延时判断}else{for (int i = 0; i<8; i++) //循环验证在curr行时,把皇后放置在第i列时{int ok = 1;//标记此行是否放置了皇后memset(k[curr], 0, sizeof k[curr]);//每次重新在此行放置皇后时,清空此行的之前放置的东西k[curr][i] = 1;//标记在curr行i列放置的皇后c[curr] = i;//表示curr行放置皇后的列数setfillcolor(BLUE);z0();solidcircle(i * 100 + 50, curr * 100 + 50, 30);//并且将此时位置画上蓝色圆for (int j = 0; j<curr; j++)//判断是否与前面的皇后位置有冲突{if (c[curr] == c[j] || curr - c[curr] == j - c[j] || curr + c[curr] == j + c[j]){//判断是否在同一列和是否会在对角线上setfillcolor(RED);solidcircle(i * 100 + 50, curr * 100 + 50, 30);//若是不合适皇后,则显示红色圆片z0();clearcircle(i * 100 + 50, curr * 100 + 50, 30);ok = 0;//如果出现冲突,则将此处的皇后撤掉,表示此行没有放置合适的皇后k[curr][i] = 0;break;//只要出现有冲突的,则跳出判断循环,把此行的皇后放置到下一列}}if (ok)//若是此行已经放置好了合适的皇后{pan(curr + 1);//进行下一行皇后位置的寻找clearcircle(i * 100 + 50, curr * 100 + 50, 30);//寻找结束之后,清除上一行皇后位置}}}}int main(){char p;//判断是否进入程序产看八皇后结果cout << "输入Y进入查看,N退出查看" << endl << "请输入:" << endl;cin >> p;while(p == 'Y')//进入产看选择循环,可多次查看两种结果展示{cout << "请输入1或者0:" << endl;cout << "提示:1查看结果,0查看动态演示" << endl;cin >> pp;memset(k, 0, sizeof k);//清零二维数组initgraph(1200, 800);//定义画布大小1200(长)*800(宽)IMAGE img1; // 定义 IMAGE1 对象loadimage(&img1, "D:\\WSX.jpg",400,250); // 读取图片到 img1 对象中putimage(801, 0, &img1); // 在左上角的坐标 (801, 0) 位置显示 IMAGE1 对象IMAGE img2; loadimage(&img2, "D:\\WSX2.jpg", 400, 250); putimage(801, 250, &img2); IMAGE img3;loadimage(&img3, "D:\\WSX3.jpg", 400, 250); putimage(801, 500, &img3);for (int i = 0; i < 800; i = i + 100)      //创建8*8的白色边框网格棋盘{for (int j = 0; j < 800; j = j + 100){setfillcolor(WHITE);rectangle(j, i, j + 100, i + 100);}}pan(0);//进入皇后的放置判断//system("pause");closegraph();//关闭画布,继续进入选择system("pause");cout << "继续查看输入Y,退出查看请输入N" << endl << "请输入:" << endl;cin >> p;}cout << "感谢使用!" << endl;system("pause");return 0;}

//选择界面    //过程动态展示   //92种结果查看显示


原创粉丝点击