P8642 [蓝桥杯 2016 国 AC] 路径之谜 题解

数据范围很小,考虑爆搜。

搜到位置 $(x,y)$ 时统计 $(x,y)$ 的贡献,即 $x$ 行与 $y$ 列的箭靶箭数减一。

容易发现,若此时 $x$ 行或 $y$ 列的箭靶箭数为 $0$,则不能走到 $x,y$,不需要往下搜。(可行性剪枝)

搜索时记录 $z_i$ 表示第 $i$ 步的位置,搜到终点后输出 $z$ 即可。

#include <cstdio>
#include <cstdlib>
int n, o, p[20], q[20], z[450], f[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
bool v[20][20];
void D(int x, int y, int d)
{
    if (x < 0 || x >= n || y < 0 || y >= n || v[x][y] || !p[x] || !q[y])
        return;
    v[x][y] = 1;
    --p[x];
    --q[y];
    z[d] = x * n + y;
    if (x == n - 1 && y == n - 1)
    {
        if (d == o)
        {
            for (int i = 1; i <= d; ++i)
                printf("%d ", z[i]);
            exit(0);
        }
    }
    else
        for (int i = 0, a, b; i < 4; ++i)
            D(x + f[i][0], y + f[i][1], d + 1);
    v[x][y] = 0;
    ++p[x];
    ++q[y];
}
int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
        scanf("%d", q + i), o += q[i];
    for (int i = 0; i < n; ++i)
        scanf("%d", p + i);
    D(0, 0, 1);
}
posted @ 2023-06-14 16:42  5k_sync_closer  阅读(7)  评论(0编辑  收藏  举报  来源