算法: 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;
}
复制代码
相关文章
相关标签/搜索