【洛谷 P1219】[USACO1.5]八皇后 Checker Challenge 题解(深度优先搜索+回溯法)

简介: **USACO1.5八皇后挑战**是关于在$n\times n$棋盘上放置棋子的,确保每行、每列及两条主对角线上各有一个且仅有一个棋子。给定$6$作为输入,输出前$3$个解及解的总数。例如,对于$6\times6$棋盘,正确输出应包括解的序列和总数。代码使用DFS解决,通过跟踪对角线占用状态避免冲突。当找到所有解时,显示前三个并计数。样例输入$6$产生输出为解的前三个排列和总数$4$。

[USACO1.5]八皇后 Checker Challenge

题目描述

一个如下的 $6 \times 6$ 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

上面的布局可以用序列 $2\ 4\ 6\ 1\ 3\ 5$ 来描述,第 $i$ 个数字表示在第 $i$ 行的相应位置有一个棋子,如下:

行号 $1\ 2\ 3\ 4\ 5\ 6$

列号 $2\ 4\ 6\ 1\ 3\ 5$

这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。
并把它们以上面的序列方法输出,解按字典顺序排列。
请输出前 $3$ 个解。最后一行是解的总个数。

输入格式

一行一个正整数 $n$,表示棋盘是 $n \times n$ 大小的。

输出格式

前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

样例 #1

样例输入 #1

6

样例输出 #1

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

提示

【数据范围】
对于 $100\%$ 的数据,$6 \le n \le 13$。

题目翻译来自NOCOW。

USACO Training Section 1.5

思路

用棋子的坐标转换得到棋子所在的对角线编号,每个棋子占据一条主对角线和一条副对角线,下一个棋子不能放在已被占据的对角线上。

AC代码

#include <iostream>
#include <cstring>
#define ms(a) memset(a, 0, sizeof(a))
#define AUTHOR "HEX9CF"
using namespace std;

const int maxn = 1005;

int n;
int a[maxn];
bool b[maxn], diag1[maxn], diag2[maxn];
int cnt = 0;

void dfs(int x)
{
   
   
    if (n == x)
    {
   
   
        cnt++;
        if(4 > cnt){
   
   

            for (int i = 0; i < n; i++)
            {
   
   
                cout << a[i] << " ";
            }
            cout << endl;
        }
    }
    for (int i = 1; i <= n; i++)
    {
   
   
        int d1 = n - x + i;
        int d2 = x + i;
        if (!b[i] && !diag1[d1] && !diag2[d2])
        {
   
   
            b[i] = 1;
            diag1[d1] = 1;
            diag2[d2] = 1;
            a[x] = i;
            dfs(x + 1);
            b[i] = 0;
            diag1[d1] = 0;
            diag2[d2] = 0;
        }
    }
}

int main()
{
   
   
    ms(a);
    ms(b);
    ms(diag1);
    ms(diag2);
    cin >> n;
    dfs(0);
    cout << cnt << endl;
    return 0;
}
目录
相关文章
|
6月前
【洛谷 P2089】烤鸡(深度优先搜索)
## 摘要: 猪猪Hanke的烤鸡问题要求找出所有配料组合,使得$10$种配料(每种$1$到$3$克)的总和等于给定美味程度$n$。输入为正整数$n$,输出为方案总数及所有符合条件的配料分配,按字典序排列。样例输入$11$,输出$10$种方案。代码采用递归搜索,先计数再打印方案。$n\leq5000$时保证数据覆盖。
33 0
|
2月前
|
算法
lanqiao OJ 1366 spfa最短路
lanqiao OJ 1366 spfa最短路
26 0
|
2月前
Leetcode第十八题(四数之和)
这篇博客介绍了LeetCode第18题“四数之和”的解法,通过排序和双指针技术来找出数组中所有和为特定值的四个不同元素的组合。
17 0
华为机试HJ44:Sudoku(数独问题,深度优先遍历DFS解法)
华为机试HJ44:Sudoku(数独问题,深度优先遍历DFS解法)
146 0
hdoj 1078 FatMouse and Cheese(记忆化搜索)
简单的记忆化搜索,和其他不一样的地方就是这个一次可以走K步,其他没啥!!
56 0
|
存储 算法 C++
剑指offer(C++)-JZ69:跳台阶(算法-动态规划)
剑指offer(C++)-JZ69:跳台阶(算法-动态规划)
|
机器学习/深度学习
【每日一题Day34】LC808分汤 | 动态规划 记忆化搜索
当我们把汤分配给某人之后,汤就没有了。每个回合,我们将从四种概率同为 0.25 的操作中进行分配选择。如果汤的剩余量不足以完成某次操作,我们将尽可能分配。当两种类型的汤都分配完时,停止操作。
66 0
|
机器学习/深度学习 算法
LeetCode打卡 52八皇后Ⅱ&53最大子序和&54螺旋矩阵
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
137 0
LeetCode打卡 52八皇后Ⅱ&53最大子序和&54螺旋矩阵
|
机器学习/深度学习
洛谷P3395-路障(BFS)
洛谷P3395-路障(BFS)
洛谷P3395-路障(BFS)
|
存储 Java Python
ACM 选手图解 LeetCode 四数相加Ⅱ
给定 4 个长度为 n 的整数数组,计算有多少个元组(i, j, k, l) 能满足: nums[i] + nums[j] + nums[k] + nums[l] == 0。
ACM 选手图解 LeetCode 四数相加Ⅱ