规则
西洋棋的皇后能够直线前进,吃掉全部遇到的棋子(即所在行,列,斜线上的全部棋子),若是棋盘上有八个皇后,则这八个皇后图和相安无事的放置在棋盘上?优化
解法
1970年与1971年,E.W.Dijkstra
与N.Writh
曾经用这个问题来说解程式.采用递归
进行八皇后所走格子的检查,为减小检查次数,则若某列检查过,则该列的其余格子就不用再检查.这种方式也称分支修建法(回溯法)
ui
代码
- 变量声明
#define N 8
int column[N + 1]; // 同栏是否有皇后,1表示有,这里是列数,从1开始,一共8列。
int rup[2 * N + 1]; // 右上至左下是否有皇后,这里是斜线,一共15条斜线,从2开始,到16。
int lup[2 * N + 1]; // 左上至右下是否有皇后,这里是斜线,一共15条斜线,从1开始,到15。
int queen[N + 1] = { 0 };
int num; // 棋盘结构数量
void backtrack(int); // 递归求解
复制代码
- 主要结构
void backtrack(int i) {
int j;
if (i > N) {
showAnswer();//展现皇后在棋盘中位置状况
}
else {
for (j = 1; j <= N; j++) {//计算的时候只要符合皇后不一样在一行,一列,一斜线上这一规则便可
if (column[j] == 1 && rup[i + j - 1] == 1 && lup[i - j + N] == 1) {
queen[i] = j;
// 设定为占用
column[j] = rup[i + j - 1] = lup[i - j + N] = 0;
backtrack(i + 1);
column[j] = rup[i + j - 1] = lup[i - j + N] = 1;
}
}
}
}
复制代码
- 完整展现
#include <stdio.h>
#include <stdlib.h>
//eight Queens-八皇后
#define N 8
int column[N + 1]; // 同栏是否有皇后,1表示有,这里是列数,从1开始,一共8列。
int rup[2 * N + 1]; // 右上至左下是否有皇后,这里是斜线,一共15条斜线,从2开始,到16。
int lup[2 * N + 1]; // 左上至右下是否有皇后,这里是斜线,一共15条斜线,从1开始,到15。
int queen[N + 1] = { 0 };
int num; // 棋盘结构数量
void backtrack(int); // 递归求解
void queens(void) {
int i;
num = 0;
for (i = 1; i <= N; i++)
column[i] = 1;
for (i = 1; i <= 2 * N; i++)
rup[i] = lup[i] = 1;
backtrack(1);
}
//思路优化
//void queen(int row) {
// if (row == n)
// total++;
// else
// for (int col = 0; col != n; col++) {
// c[row] = col;
// if (is_ok(row))
// queen(row + 1);
// }
//}
void showAnswer() {
int x, y;
printf("\n皇后位置展现%d\n", ++num);
for (y = 1; y <= N; y++) {
for (x = 1; x <= N; x++) {
if (queen[y] == x) {
printf(" Q");
}
else {
printf(" .");
}
}
printf("\n");
}
}
//i表示从棋盘的第i行出法
void backtrack(int i) {
int j;
if (i > N) {
showAnswer();//展现皇后在棋盘中位置状况
}
else {
for (j = 1; j <= N; j++) {//计算的时候只要符合皇后不一样在一行,一列,一斜线上这一规则便可
if (column[j] == 1 && rup[i + j - 1] == 1 && lup[i - j + N] == 1) {
queen[i] = j;
// 设定为占用
column[j] = rup[i + j - 1] = lup[i - j + N] = 0;
backtrack(i + 1);
column[j] = rup[i + j - 1] = lup[i - j + N] = 1;
}
}
}
}
int main() {
queens();
return 0;
}
复制代码