• [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("
    ");
    	}
    }
    
    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();
    }
    
  • 相关阅读:
    linux就该这么学.pdf
    linux中shell编辑小技巧
    相关功能分享
    现代操作系统第三版高清.pdf中文版免费下载
    linux高性能服务器编程pdf免费下载
    git每次更新都需要输入账号密码,如何解决?
    Python 面向对象
    模块和包
    Python常用模块(collections、 time、 random、 os 、sys、序列化模块)
    内置函数和匿名函数(lambda)
  • 原文地址:https://www.cnblogs.com/by-sknight/p/10884504.html
Copyright © 2020-2023  润新知