首页 > 其他分享 >洛谷-P3869 [TJOI2009] 宝藏

洛谷-P3869 [TJOI2009] 宝藏

时间:2024-08-02 11:40:59浏览次数:12  
标签:洛谷 cin int text pos beg P3869 new 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;
}

标签:洛谷,cin,int,text,pos,beg,P3869,new,TJOI2009
From: https://www.cnblogs.com/carboxylBase/p/18338411

相关文章

  • 洛谷 P1052 [NOIP2005 提高组] 过河
    原题https://www.luogu.com.cn/problem/P1052题目描述在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:1,⋯,L......
  • 洛谷P3161 [CQOI2012] 模拟工厂 贪心策略的思考
    P3161[CQOI2012]模拟工厂传送门:模拟工厂问题描述:初始的生产力和商品分别为1和0。每一个时刻可以选择两个动作:生产力+1或者生产生产力数量的商品。现在有很多个订单,每个订单有三个部分:时间t,需要多少商品p,可以获得的价值v。现在需要决定各个时刻的动作选择,以及订单是否接取,以期......
  • 洛谷题单指南-前缀和差分与离散化-P3029 [USACO11NOV] Cow Lineup S
    原题链接:https://www.luogu.com.cn/problem/P3029题意解读:不同的坐标位置有不同种类的牛,要计算一个最小的区间,包括所有种类的牛。解题思路:由于坐标位置不连续,并且数值范围较大,因此需要离散化处理,将坐标处理成1~n连续分布由于种类编号数值范围也比较大,也需要离散化处理,去重后的......
  • 洛谷P2801 教主的魔法之分块板子
    洛谷P2801题解传送锚点摸鱼环节教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是\(N\)个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为\(1,2,\ldots,N\)。每个人的身高一开始都是不超过\(1000\)......
  • 洛谷 B3612 【深进1.例1】求区间和
    "这道题也太水了吧,模拟就行了!""数据范围...""好像不行呀""呜呜~~TLE!"献上暴力代码!#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+5;intn,a[N],m;signedmain(){ios::sync_with_stdio(0);cin.tie(0);......
  • 洛谷题单指南-前缀和差分与离散化-P4552 [Poetize6] IncDec Sequence
    原题链接:https://www.luogu.com.cn/problem/P4552题意解读:对一组数字序列,进行若干次区间+1或者-1操作,最终使得所有数字一样,计算最少的操作次数,以及能得到多少种不同序列。解题思路:要使得序列每一个数字都相同,则其差分除了第一项之外其余项都是0。因此,问题转化为:给定一个差分数......
  • 洛谷题单指南-前缀和差分与离散化-P2882 [USACO07MAR] Face The Right Way G
    原题链接:https://www.luogu.com.cn/problem/P2882题意解读:一个有F、B组成的序列,每次可以翻转k个连续子序列,翻转:F->B,B->F,计算最少翻转多少次可以将序列都变成F,并求相应的k。解题思路:为方便处理,设F为1,B为01、朴素做法枚举k:1~n  枚举序列,一旦遇到0,就将连续k个字符翻转,如果可......
  • 洛谷P2696之慈善的约瑟夫——题解
    洛谷P2696题解[传送锚点](P2696慈善的约瑟夫-洛谷|计算机科学教育新生态(luogu.com.cn))比不过大佬,从蒟蒻做起选择比较水有意思的解法——用队列模拟(还是窝太弱了)正片开始考虑队列模拟,因为每次都是假的剔除,所以我们的目标是找到每回游戏的最终存活者。将不被剔除,......
  • 洛谷-P1171-售货员的难题
    Abstract传送门也算是状压dp模板题?不过这个数据给的有点阴间了,空间不够用,需要搞一个奇妙的优化。idea所谓状压,就是用数字表示当前状态,比如说0110100这个数字,我们可以把01分别看作是是否到达过第i个点的标记。那么我们可以用dp[i][j]表示第i个状态下,快递员到达j......
  • 洛谷题单指南-前缀和差分与离散化-P1083 [NOIP2012 提高组] 借教室
    原题链接:https://www.luogu.com.cn/problem/P1083题意解读:已知第i天有r[i]个教室可以供租借,有m个租借教室的订单,第i订单需要在第s[i]~t[i]天区间内租借d[i]个教室,计算是否全部订单都能满足,如果不满足要输出从第几个订单开始不满足。解题思路:1、朴素做法枚举1~m个订单,通过差分......