zoukankan      html  css  js  c++  java
  • DFS入门——八皇后问题输出方案

    题目出处:《信息学奥赛一本通》第五章上机练习2

    题目描述

    要在国际象棋棋盘((8 imes 8) 的棋盘)中放 (8) 个皇后,使任意两个皇后都不能互相吃。(提示:皇后能吃同一行、同一列、同一对角线的任意棋子。)

    输入格式

    无输入。

    输出格式

    按给定顺序和格式输出所有八皇后问题的解(见样例输出)

    样例输入

    无输入。

    样例输出

    No. 1
    1 0 0 0 0 0 0 0
    0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 1
    0 0 0 0 0 1 0 0
    0 0 1 0 0 0 0 0
    0 0 0 0 0 0 1 0
    0 1 0 0 0 0 0 0
    0 0 0 1 0 0 0 0
    No. 2
    1 0 0 0 0 0 0 0
    0 0 0 0 0 1 0 0
    0 0 0 0 0 0 0 1
    0 0 1 0 0 0 0 0
    0 0 0 0 0 0 1 0
    0 0 0 1 0 0 0 0
    0 1 0 0 0 0 0 0
    0 0 0 0 1 0 0 0
    ... 以下省略
    

    题目分析

    这道题其实和我们之前的“八皇后问题”非常类似。
    只不过之前只是计数,而我们这里需要输出所有方案,所以在原来的基础上添加一个输出方案的函数 output() 即可。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    int ans[9], cnt; // ans[i]用于记录第i行皇后列号,cnt用于记录方案数
    // attack函数用于判断(x1,y1)和(x2,y2)两个点是否会互相攻击
    // 返回true:会互相攻击到;返回false:不会互相攻击到
    bool attack(int x1, int y1, int x2, int y2) {
        return x1==x2||y1==y2||abs(x1-x2)==abs(y1-y2);
    }
    // output函数用于输出一种方案
    void output() {     // 新增的用于输出方案的函数
        cnt ++;     // 找到一个方案,cnt++
        cout << "No. " << cnt << endl;  // 输出方案id
        for (int i = 1; i <= 8; i ++) { // 输出方案
            for (int j = 1; j <= 8; j ++)
                cout << (j > 1 ? " " : "") << (j == ans[i]);
            cout << endl;
        }
    }
    // f函数用于在第id行尝试性地放一个i,然后递归地去id+1行放
    void f(int id) {
        if (id > 8) {   // 说明前8行已经放好了
            output();   // 调用output函数,因为这里要输出了
            return;     // 程序可直接返回
        }
        for (int i = 1; i <= 8; i ++) { // 尝试在第id行第i列放皇后
            bool flag = true;   // flag用于标识是否能放
            for (int j = 1; j < id; j ++) {
                if (attack(id, i, j, ans[j])) { // (id,i)和(j,ans[j])冲突
                    flag = false;              // 将flag设为false标识不能放
                    break;
                }
            }
            if (flag) { // 如果循环结束flag仍为true说明i能放
                ans[id] = i;    // 能放就先放上
                f(id+1);        // 然后递归进行下一行的放置
            }
        }
    }
    int main() {
        f(1);   // 从第1行开始放
        return 0;
    }
    
  • 相关阅读:
    zoj 3627#模拟#枚举
    Codeforces 432D Prefixes and Suffixes kmp
    hdu 4778 Gems Fight! 状压dp
    CodeForces 379D 暴力 枚举
    HDU 4022 stl multiset
    手动转一下田神的2048
    【ZOJ】3785 What day is that day? ——KMP 暴力打表找规律
    poj 3254 状压dp
    C++中运算符的优先级
    内存中的数据对齐
  • 原文地址:https://www.cnblogs.com/quanjun/p/13246166.html
Copyright © 2011-2022 走看看