[Aizu] ALDS1_13_A: 8 Queens Problem

Posted by-sknight

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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();
}

以上是关于[Aizu] ALDS1_13_A: 8 Queens Problem的主要内容,如果未能解决你的问题,请参考以下文章

Stack,( Aizu - ALDS1_3_A)

Exhaustive Serch ( Aizu - ALDS1_5_A )

有根树的表达 Aizu - ALDS1_7_A: Rooted Trees

Aizu - ALDS1_4_C Dictionary

Aizu - ALDS1_7_C Tree Walk

Aizu - ALDS1_1_CPrime Numbers(素数筛法)