首页 > 其他分享 >AT_abc348_d [ABC348D] Medicines on Grid 题解

AT_abc348_d [ABC348D] Medicines on Grid 题解

时间:2024-10-21 11:24:20浏览次数:1  
标签:ch ma int 题解 Medicines bfs leq abc348 bx

题目传送门

题目大意:

给定一个 \(n \times m\) 的地图,要求从起点 S 走到终点 T,每移动 \(1\) 个会消耗 \(1\) 点能量,障碍 # 不能走,空地为.可以走,体力消耗至 \(0\) 也无法移动,地图位置 \((x_i,y_i)\) 有一瓶可以变成 \(e_i\) 体力的药,可以选择是否喝。

问能否抵达终点,可以输出 Yes,否则输出 No

数据范围:\(1 \leq n,m \leq 200,1 \leq x_i \leq n,1 \leq y_i \leq m,1 \leq e_i \leq n \times m\)。

题目分析:

(一眼 bfs 板题,结果赛时用了标记是否走过+优先队列的假做法 WA 了 3 个点没调出来)

这题需要判断,因为吃药这个性质特殊,是变成对应的体力值 \(e\),而不是增加体力值 \(e\),存在后效性,不能使用标记是否走过+优先队列,所以需要开一个 ma[][] 数组记录走到某点的最大能量,当 \(w_{x,y}>ma_{x,y}\) 才继续搜索,切记每走到有药的地方直接先让 \(w_{x,y} \gets \max(w_{x,y},a_{x,y})\),再判断即可(a 数组存图)。

时间复杂度:\(O(nm)\),含有较大常数。

Code:

#include<bits/stdc++.h>
using namespace std;
const int N=205;
const int dx[4]={0,0,1,-1};
const int dy[4]={1,-1,0,0};//遍历方向
int n,m,k,bx,by,ex,ey,a[N][N],ma[N][N];
//(bx,by)为起点,(ex,ey)为终点,a[][]存图,障碍为 -1,自然数能走,正整数表示有药,ma[i][j]存走到(i,j)的最大能量
struct dat//自从打过 CF 的题结构体就再也不敢命名为 data
{
	int x,y,w;
};//结构体存走到(x,y)有 w 能量
void bfs(int x,int y)
{
	queue <dat> q;//开普通队列即可
	q.push((dat){x,y,a[x][y]});
	ma[x][y]=a[x][y];
	while(!q.empty())
	{
		dat now=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			int xx=now.x+dx[i];
			int yy=now.y+dy[i];
			int ww=now.w-1;
			if(xx==ex&&yy==ey)//是否抵达终点
			{
				printf("Yes");
				exit(0);//结束程序
			}
			ww=max(ww,a[xx][yy]);//走到 (xx,yy) 的最大能量
			if(xx<1||xx>n||yy<1||yy>m||a[xx][yy]==-1||ww<=ma[xx][yy]||ww<=0) continue;//判断越界、障碍、能量,若当前能量不超过最大能量也要停止下传
			q.push((dat){xx,yy,ww});
			ma[xx][yy]=ww;//更新走到 (xx,yy) 的最大能量
		}
	}
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			char ch;
			cin>>ch;
			if(ch=='S') bx=i,by=j;//起点
			if(ch=='T') ex=i,ey=j;//终点
			if(ch=='#') a[i][j]=-1;//障碍
		}
	cin>>k;
	for(int i=1;i<=k;i++)
	{
		int x,y,w;
		cin>>x>>y>>w;
		a[x][y]=w;//标记(x,y)有可以变成 w体力药 
	}
	if(!a[bx][by])//若初始位置没有能量,无法行动,不用进入 bfs,直接输出 -1
	{
		printf("No");
		return 0;
	}
	bfs(bx,by);
	printf("No");
	return 0;
}

标签:ch,ma,int,题解,Medicines,bfs,leq,abc348,bx
From: https://www.cnblogs.com/lunjiahao/p/18489076

相关文章

  • AT_abc374_e [ABC374E] Sensor Optimization Dilemma 2 题解
    洛谷题目传送门AT题目传送门题目大意:给定\(n\)道工序,你有\(X\)元的资金,对于第\(i\)道工序,有两种机器供你选择,第一种机器可以花费\(P_i\)元处理\(A_i\)个产品,第二种机器可以花费\(Q_i\)元处理\(B_i\)个产品。钦定第\(i\)天处理的产品个数为\(W_i\),求在总花费......
  • UVA11294 Wedding 题解
    洛谷题目传送门前排提示:本题需要用到知识点2-SAT以及强联通分量,模板传送门P4782【模板】2-SAT。题目大意:有至多\(30\)对夫妻将会参加一个婚宴。他们将会坐在一个长桌子的两边。新郎新娘坐在彼此相对的一端并且新娘带着一个头饰使得她看不到和她坐在同一边的人。夫妻坐在......
  • SP9685 ZTC - Zombie’s Treasure Chest 题解
    洛谷题目传送门双倍经验简单题。对于空间大小为\(s1\timess2\)时,显然最多可得到的价值为\(\max(s2\timesv1,s1\timesv2)\),剩下小于\(s1\timess2\)的部分选一个占用空间大的枚举就好。时间复杂度:\(O(T\lfloor\frac{m}{\max(s1,s2)}\rfloor)\),其中\(m=n\bmo......
  • 【题解】Solution Set - NOIP2024集训Day57 字符串
    【题解】SolutionSet-NOIP2024集训Day57字符串https://www.becoder.com.cn/contest/5653「CF213E」TwoPermutations「CF961F」k-substrings「CF580E」KefaandWatch「CF504E」MishaandLCPonTree......
  • Codeforces Round 979 div2 个人题解(A~E)
    CodeforcesRound979div2个人题解(A~E)Dashboard-CodeforcesRound979(Div.2)-Codeforces火车头#define_CRT_SECURE_NO_WARNINGS1#include<algorithm>#include<array>#include<bitset>#include<cmath>#include<cstdio>#inc......
  • P11211 随机数生成器 题解
    前置知识:原根,exCRT。首先\(t=1\)是容易的,直接相邻的除一下即可。否则考虑询问除连续的\(5\)个数,分别为\(a_0,a_1,\cdots,a_4\)。首先特判掉存在\(a_i=0\)的情况,此时直接枚举\(s\)即可。我们先求出\(p\)的一个原根\(g\),设离散对数\(\log(x)=y\)表示\(g^y\equiv......
  • 牛客周赛Round64-B题题解
    牛客周赛Round64-B题题解题目描述:小红拿到了一个正整数,请你帮小红将其表示为幂(a^b)的形式。输入描述:一个正整数2<=x<=10^5输出描述:`第一行输出x。接下来每一行输出一个幂的表达式。请按指数从小到大的顺序输出。示例1输入16输出16=16^1=4^2=2^4解题思路:......
  • 【秋招笔试-支持在线评测】10.19京东秋招(已改编)-三语言题解
    ......
  • 【秋招笔试-支持在线评测】10.19小米秋招(已改编)-研发岗题解
    ......
  • [20241024] T3 题解
    细节挺多的。题意有一个长度为\(n\)的数组\(a\)和一个长度为\(m\)的队列\(q\),初始时\(q\)中的元素和为\(0\)。对\(x=1,2,\cdots,n\)进行如下操作:如果队首元素\(q_1<a_x\),则\(q\)弹出队首,将\(a_x\)插入队尾。在操作结束后,定义数组\(a\)的权值为\(q\)......