洛谷-P3869 [TJOI2009] 宝藏

Abstract

传送门
本题是状态压缩+记忆化BFS的典型例子。

Idea

要求从出发点到终点的最短步数, BFS 自然是首选的方法,那么,如何构造搜索的每一个节点呢?考虑到机关的数量比较小,最多 10 种,我们可以考虑用状态压缩去描述机关当前的状态,然后再记录当前的横纵坐标,以及行走的步数即可。值得一提的是,这题需要记忆化!否则会 MLE 。

Code

#include <bits/stdc++.h>
using namespace std;

int r, c;
int mat[40][40];
struct Node
{
    int mode;
    int x, y, t;
};
Node beg_pos, end_pos;
int k;
typedef pair<int, int> pii;
pii cause[20];
pii effect[20];
int minT[40][40][3000];

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cin >> r >> c;
    for (int i = 1; i < r + 1; i++)
    {
        string text;
        cin >> text;
        for (int j = 1; j < c + 1; j++)
        {
            if (text[j - 1] == '#')
            {
                mat[i][j] = 0;
            }
            else
            {
                if (text[j - 1] == 'S')
                {
                    beg_pos.x = i, beg_pos.y = j;
                }
                if (text[j - 1] == 'T')
                {
                    end_pos.x = i, end_pos.y = j;
                }
                mat[i][j] = 1;
            }
        }
    }
    cin >> k;
    for (int i = 0; i < k; i++)
    {
        cin >> cause[i].first >> cause[i].second >> effect[i].first >> effect[i].second;
    }
    beg_pos.mode = 0;
    beg_pos.t = 0;
    queue<Node> q;
    q.push(beg_pos);
    int vx[4] = {1, 0, -1, 0};
    int vy[4] = {0, 1, 0, -1};
    memset(minT, 0x3f3f3f3f, sizeof minT);
    while (!q.empty())
    {
        Node now_pos = q.front();
        q.pop();
        if (now_pos.x == end_pos.x && now_pos.y == end_pos.y)
        {
            cout << now_pos.t << endl;
            return 0;
        }
        for (int i = 0; i < 4; i++)
        {
            Node new_pos;
            new_pos.x = now_pos.x + vx[i];
            new_pos.y = now_pos.y + vy[i];
            if (new_pos.x >= r + 1 || new_pos.x <= 0 || new_pos.y >= c + 1 || new_pos.y <= 0)
            {
                continue;
            }
            int value = mat[new_pos.x][new_pos.y];
            for (int j = 0; j < k; j++)
            {
                if ((1 << j) & now_pos.mode)
                {
                    if (effect[j].first == new_pos.x && effect[j].second == new_pos.y)
                    {
                        value = 1 - value;
                    }
                }
            }
            if (value == 0)
            {
                continue;
            }
            else
            {
                new_pos.mode = now_pos.mode;
                new_pos.t = now_pos.t + 1;
                for (int j = 0; j < k; j++)
                {
                    if (cause[j].first == new_pos.x && cause[j].second == new_pos.y)
                    {
                        if ((1 << j) & new_pos.mode)
                        {
                            new_pos.mode -= (1 << j);
                        }
                        else
                        {
                            new_pos.mode += (1 << j);
                        }
                    }
                }
                if (minT[new_pos.x][new_pos.y][new_pos.mode] > new_pos.t)
                {
                    minT[new_pos.x][new_pos.y][new_pos.mode] = new_pos.t;
                }
                else
                {
                    continue;
                }
                q.push(new_pos);
            }
        }
    }
    return 0;
}
posted @   carboxylBase  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示