[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();
}

原文地址:https://www.cnblogs.com/by-sknight/p/10884504.html

时间: 2024-08-30 07:48:15

[Aizu] ALDS1_13_A: 8 Queens Problem的相关文章

【算法】N Queens Problem

/* ** 目前最快的N皇后递归解决方法 ** N Queens Problem ** 试探-回溯算法,递归实现 */ #include "stdafx.h" #include "iostream" #include <math.h> using namespace std; #include "time.h" // sum用来记录皇后放置成功的不同布局数:upperlim用来标记所有列都已经放置好了皇后. long sum = 0,

惊叹计算机运行速度的提升---以n Queens 问题为例

1 介绍 实现了书<Data Structures and Program design in C++>(Robert L. Kruse and Alexander J. Ryba, 2000)中的188页的基于回溯策略的递归算法solve_from,该算法能够计算n Queens问题的解.选择不同的n作为棋盘大小,能够得出不同棋盘大小的Queens问题的解即执行时间. 该书出版时间为2000年,那么使用的计算机大概为1999年左右的.该书给出了执行的结果数据.我在我的电脑上採用相同的代码和算

Jeff Somers&#39;s N Queens Solutions 最快的n皇后算法

1 /* Jeff Somers 2 * 3 * Copyright (c) 2002 4 * 5 * [email protected] 6 * or 7 * [email protected] 8 * 9 * April, 2002 10 * 11 * Program: nq 12 * 13 * Program to find number of solutions to the N queens problem. 14 * This program assumes a twos compl

PAT A1128 N Queens Puzzle (20 分)

The "eight queens puzzle" is the problem of placing eight chess queens on an 8×8 chessboard so that no two queens threaten each other. Thus, a solution requires that no two queens share the same row, column, or diagonal. The eight queens puzzle

2n皇后问题

在蓝桥杯基础训练题中,出现这样一道题目: 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行.同一列或同一条对角线上.问总共有多少种放法?n小于等于8. 输入格式 输入的第一行为一个整数n,表示棋盘的大小. 接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后. 输出格式 输出一个整数,表示总

ubuntu下面安装glpk

然而在我的电脑里.安装命令为sudo apt-get install glpk-utils 作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4156204.html glpk是一个开源的求解线性规划的包. 添加源: deb http://us.archive.ubuntu.com/ubuntu saucy main universe 更新源并安装: sudo apt-get update sudo apt-get install glpk

图实践经典问题一览

图算是数据结构中比较难的问题,但是在实际中解决的问题也更多. 其中,在图结构中涉及的问题主要有: 图的存储: 邻接表(Adjacency list):为每个节点建立一个链表存放与之连接的点. 邻接矩阵(Adjacency matrix):n*n的矩阵,有边的是1,无边的是0. 最短路径: Dijkstra:记录起点能够到达的所有节点的最短路径,这样,我们要找的终点一定在其中啊. DIST(w) = min(DIST(w), DIST(u) + c(u, w)) 代码实现示例: package c

n皇后2种解题思路与代码-Java与C++实现

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了n皇后问题的解题思路,并分别用java和c++实现了过程,最后,对于算法改进,使用了位运算. 一.问题抛出与初步解题思路 问题描述:八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上. 转化规则:其实八皇后问题可以推广为更一般的n皇后

八皇后以及N皇后问题分析

八皇后是一个经典问题,在8*8的棋盘上放置8个皇后,每一行不能互相攻击. 因此 拓展出 N皇后问题. 下面慢慢了解解决这些问题的方法: 回溯法: 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法. 回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试. 在现实中,有很多问题往往需要我们把其所有可能穷举出来,然后从中找出满足某种要求的可能或最优的情况,从而得到整个问题的解. 回溯算法就是解决这种问题的“通用算法”,有“万能算法”之称. N皇后问题在N增大时就是这样一个解