📄 main.c
字号:
/////////////////////////////////////////////////////////////////////
// //
// 程序名称: LED 点阵显示八皇后解 (for ELITE-III) //
// //
// 作 者: ZeroStar (根据网络上的 DOS 版程序改写) //
// //
// 联系方式: boylinxing@tom.com //
// //
// 创建日期: 2007-01-27 //
// //
// 修改日期: 2007-01-27 //
// //
// 当前版本: 0.1 //
// //
// 文件功能: 求解八皇后问题,并用 8 x 8 LED 点阵显示 //
// //
// 在 8 x 8 格的国际象棋棋盘上摆放八个皇后,使其不能互相攻 //
// 击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。 //
// 本程序用 8 x 8 LED 点阵显示所有解。 //
// //
/////////////////////////////////////////////////////////////////////
#include <reg51.h>
#include "led8x8.h"
#define DEMO_SPEED 10 // 设置演示速度,值越大演示越慢,最大值为 255
unsigned char x[8]; // 解数组 x[i], 记录第 i 号皇后放置的列号。
// 根据题意 8 个皇后应分别占据 8 行,令其中
// 第 i 号皇后占据第 i 行,则只须确定 8 个
// 皇后各自占据的列号就可以确定一组解。数
// 组元素 x[0] ~ x[7] 分别用于存放求得的第
// i 号皇后占据的列号。如 x[0] = 3 表示第
// 0 号皇后放置在第 0 行第 3 列,依此类推。
unsigned char a[8]; // 纵列(|)允许标记数组 a[j]
unsigned char b[15]; // 左斜行(/)允许标记数组 b[i + j]
unsigned char c[15]; // 右斜行(\)允许标记数组 c[i - j]
/*
* 函数:show_result
* ------------------------------------------------------------------
* 将解数组 x[] 中当前求得的一个解,转换成 8 x 8 LED 点阵显示所需的
* 点阵数据并用 LED 点阵显示
*/
void show_result(unsigned char x[])
{
unsigned char mat[8]; // 用于LED点阵输出的点阵数据
unsigned char i;
for (i = 0; i < 8; i++) { // 根据当前解构造点阵数据
mat[i] = ~(0x01 << x[i]);
}
for (i = 0; i < DEMO_SPEED; i++) { // LED 点阵扫描显示当前解
led8x8_display(mat);
}
}
/*
* 函数:queen_init
* ------------------------------------------------------------------
* 初始化标记数组,将所有纵列、左斜列、右斜列标记为未被占据的。
*/
void queen_init(void)
{
unsigned char i;
for (i = 0; i < 8; i++) a[i] = 1;
for (i = 0; i < 15; i++) b[i] = 1;
for (i = 0; i < 15; i++) c[i] = 1;
}
/*
* 函数:queen
* ------------------------------------------------------------------
* 递归法求解八皇后问题的所有解,每求得一个解,显示输出。
*/
void queen(unsigned char i) reentrant
{
unsigned char j;
for (j = 0; j < 8; j++) { // 对第 i 行的 8 列逐列扫描
if (a[j] && b[i + j] && c[i - j + 7]) {
// 如果找到可以放置的列
x[i] = j; // 放置第 i 号皇后
a[j] = 0;
b[i + j] = 0;
c[i - j + 7] = 0;
if (i < 7) { // 如果 8 个皇后还没放完
queen(i + 1); // 放置下一个
} else { // 否则
show_result(x); // 输出当前求得的一个解
}
a[j] = 1; // 拿掉第 i 号皇后
b[i + j] = 1;
c[i - j + 7] = 1;
}
}
}
/*
* 函数:main
* ------------------------------------------------------------------
* 主函数
*/
void main(void)
{
queen_init(); // 初始化标记数组
while (1) { // 循环演示所有解
queen(0); // 放置第 0 号皇后
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -