八皇后问题的动态显示

问题介绍

编辑

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n1×n1,而皇后个数也变成n2。而且仅当 n2 ≥ 1 或 n1 ≥ 4 时问题有解。

八皇后问题最早是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出。之后陆续有数学家对其进行研究,其中包括高斯和康托,并且将其推广为更一般的n皇后摆放问题。八皇后问题的第一个解是在1850年由弗朗兹·诺克给出的。诺克也是首先将问题推广到更一般的n皇后摆放问题的人之一。1874年,S.冈德尔提出了一个通过行列式来求解的方法,这个方法后来又被J.W.L.格莱舍加以改进。

艾兹格·迪杰斯特拉在1972年用这个问题为例来说明他所谓结构性编程的能力。

八皇后问题出现在1990年代初期的著名电子游戏第七访客中。

八皇后核心代码: 


#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秒

}2

 

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;

}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值