[Aizu] ALDS1_13_A: 8 Queens Problem

Solution

Analysis

很经典的8皇后问题, 题目中已给出了几个皇后的位置并且不允许更改这几个皇后的位置
要求的输出是8*8的棋盘
可以使用递归的思路来求解

Design

使用了1个int数组来存储每行皇后的位置
使用了3个bool数组来判断当前列, 主对角线, 副对角线是否有冲突
设计求解函数
使用栈来存储中间的数据,(例如正在处理第3行, 然后放置到了第4列, 之后要去第4行放置皇后, 此时需要将第三行的行号, 以及处理到了哪个位置先存储起来)
处理的过程中, 如果遇到了不能更改的行, 则直接去下一行, 如果全部行都处理完成了, 那么就可以输出然后结束程序.
至于普通的情况, 先判断之前是不是放置过了皇后, 如果是的话, 将皇后先拿起(还需要修改列, 主对角线, 副对角线冲突的数组), 找到了位置, 将皇后放进去(继续修改列, 主对角线, 副对角线冲突的数组), 然后处理下一行

Code

#include <bits/stdc++.h>
using namespace std;

int queen_in_rows[8];
bool col_free[8], upward_free[15], downward_free[15];
bool can_change[8];

void print_board() {
	int i, j;
	for (i = 0; i < 8; i++) {
		for (j = 0; j < queen_in_rows[i]; j++)
			printf(".");
		printf("Q");
		for (j = queen_in_rows[i] + 1; j < 8; j++)
			printf(".");
		printf("\n");
	}
}

void solution() {
	stack<pair<int, int> > S;
	pair<int, int> P;
	int row, col;
	S.push(make_pair(0, 0));
	while (1) {
		P = S.top();	S.pop();
		row = P.first;
		col = P.second;
		// 如果全部处理完了, 退出
		if (row == 8) break;
		// 如果当前行输入中已给出, 直接处理下一行
		if (!can_change[row]) {
			// cout << "can't change line " << row << endl;
			S.push(make_pair(row + 1, 0));
			continue;
		}
		// 如果该行之前放置过皇后, 那么将该皇后拿起, 然后查找位置从下一列开始
		if (queen_in_rows[row] != -1) {
			queen_in_rows[row] = -1;
			col_free[col] = true;
			upward_free[row + col] = true;
			downward_free[row - col + 7] = true;
			col++;
		}
		// 尝试寻找可以放置皇后的位置
		while (col < 8) {
			if (col_free[col] && upward_free[row + col] 
					&& downward_free[row - col + 7])
				break;
			col++;
		}
		// 如果没有找到, 则返回上一行处理
		if (col == 8) 
			continue;
		// 如果找到了, 则将皇后放入
		// cout << "line " << row << " put queen in " << col << endl;
		queen_in_rows[row] = col;
		col_free[col] = false;
		upward_free[row + col] = false;
		downward_free[row - col + 7] = false;
		// 保存当前行的信息, 然后查找下一行
		S.push(make_pair(row, col));
		S.push(make_pair(row + 1, 0));
	}
	while (!S.empty())
		S.pop();
	print_board();
}

int main(void) {
	int i, k, row, col;
	for (i = 0; i < 8; i++) {
		queen_in_rows[i] = -1;
		col_free[i] = true;
		upward_free[i] = true;
		downward_free[i] = true;
		can_change[i] = true;
	}
	for (i = 8; i < 15; i++) {
		upward_free[i] = true;
		downward_free[i] = true;
	}
	scanf("%d", &k);
	while (k--) {
		scanf("%d %d", &row, &col);
		queen_in_rows[row] = col;
		can_change[row] = false;
		col_free[col] = false;
		upward_free[row + col] = false;
		downward_free[row - col + 7] = false;
	}
	solution();
}
posted @ 2019-05-18 07:35  by-sknight  阅读(364)  评论(0编辑  收藏  举报