算法: Eight Queens-八皇后問題

規則


西洋棋的皇后能夠直線前進,吃掉全部遇到的棋子(即所在行,列,斜線上的全部棋子),若是棋盤上有八個皇后,則這八個皇后圖和相安無事的放置在棋盤上?優化

解法


1970年與1971年,E.W.DijkstraN.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;
}
複製代碼
相關文章
相關標籤/搜索