規則
西洋棋的皇后能夠直線前進,吃掉全部遇到的棋子(即所在行,列,斜線上的全部棋子),若是棋盤上有八個皇后,則這八個皇后圖和相安無事的放置在棋盤上?優化
解法
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;
}
複製代碼