跳转至

一本通-1213:八皇后问题(回溯+搜索)

【题目描述】 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。

【输入】 (无)

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

【输入样例】 (无)

【输出样例】

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


这道题目限定了输出的格式,会发现和正常的输出还是有一点差距的,借用博客里的一张图:

在这里插入图片描述

发现其实搜索思路仍然不变,只是在输出的时候,将预先设定的行和列进行了交换。

#include <iostream>
#include <iomanip>
#include <vector>
#include <cmath>
#include <string>
#include <climits>
#include <cstdio>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <set>
#include <algorithm>

using namespace std;

int n;
vector<int> res(8, -1);
int cnt = 0;
vector<vector<int> > grid(8, vector<int>(8));

bool canPlace(int row, int col)
{
    for (int i = 0; i < row; ++i) {
        if (res[i] == col || abs(row - i) == abs(res[i] - col))
            return false;
    }

    return true;
}

void DFS(int row, int n)
{
    for (int col = 0; col < n; ++col) {
        if (canPlace(row, col)) {
            res[row] = col;
            if (row == n - 1) {
                ++cnt; //找到一种解决方案
                cout << "No. " << cnt << endl;
                for (int i = 0; i < 8; ++i) grid[res[i]][i] = 1;
                for (int i = 0; i < 8; ++i) {
                    for (int j = 0; j < 8; ++j) {
                        cout << grid[i][j];
                        if (j != n - 1) cout << ' ';
                    }
                    cout << endl;
                }

                for (int i = 0; i < 8; ++i)
                    fill(grid[i].begin(), grid[i].end(), 0);
            }
            else DFS(row + 1, n);
        }
    }
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> n;

    DFS(0, 8);

    return 0;
}