题目传送门
题目大意
题目描述
有一个 H H H 行和 W W W 列的网格。 ( i , j ) (i, j) (i,j) 表示位于从上往下第 i i i 行和从左往右第 j j j 列的单元格。每个单元格有字符 A i , j A_{i,j} Ai,j :
.
:空单元格。#
:一个障碍物。S
:空单元格和起点。T
:空单元格和目标点。
高桥可以通过消耗 1 1 1 能量从当前单元格移动到上下左右的空单元格。如果能量为 0 0 0 ,他就无法移动,也无法离开网格。
网格中有 N N N 种药。 第 i i i 种药位于空格 ( R i , C i ) (R_i, C_i) (Ri,Ci) 处,可以用来把能量 变成 E i E_i Ei 。注意,能量并不一定会增加。他可以在当前格子中使用药物。使用过的药物会消失。
高桥以 0 0 0 的能量从起点开始,并希望达到目标点。请判断这是否可行。
数据与约定
- 1 ≤ H , W ≤ 200 1 \leq H, W \leq 200 1≤H,W≤200。
-
A
i
,
j
A_{i, j}
Ai,j 是
.
、#
、S
和T
中的一个。 S
和T
都恰好存在一次。- 1 ≤ N ≤ 300 1 \leq N \leq 300 1≤N≤300。
- 1 ≤ R i ≤ H 1 \leq R_i \leq H 1≤Ri≤H。
- 1 ≤ C i ≤ W 1 \leq C_i \leq W 1≤Ci≤W。
- 对于所有 i ≠ j i \neq j i=j : : : ( R i , C i ) ≠ ( R j , C j ) . (R_i, C_i) \neq (R_j, C_j) . (Ri,Ci)=(Rj,Cj).
-
A
R
i
,
C
i
A_{R_i, C_i}
ARi,Ci 不是
#
. - 1 ≤ E i ≤ H W 1 \leq E_i \leq HW 1≤Ei≤HW。
解题思路
这道题目就是简单粗暴的搜索,尝试上下左右行走,遇到障碍物就停止,遇到能量就加上,直到到达终点或者搜索完毕。需要注意的是这道题目最好不要标记,如果你写的是普通的标记,那么我找到了一组 hack 数据。
输入:
1 7
..S...T
2
1 1 114514
1 3 2
输出:
Yes
显然,你不可以从起点出发直接朝终点走去,因为这样到达不了终点。所以你必须得先走到
(
1
,
1
)
(1,1)
(1,1) 得到能量再朝终点走去,但是在往返途中,你会经过你之前走过的点,因此你不能进行标记,除非你判断此点是否被走过两次以上但是一般不会这样。
CODE:
#include <bits/stdc++.h>
using namespace std;
//#define int long long
int h, w, sx, sy, ex, ey;
char c[410][410];
int a[410][410], ans[410][410];
struct node{
int x, y;
int nengliang;
};
int dx[] = {0, -1, 1, 0};
int dy[] = {1, 0, 0, -1};
queue<node> q;
void bfs() {
q.push({sx, sy, a[sx][sy]});
while (!q.empty()) {
node t = q.front();
q.pop();
if (t.nengliang < 0)
continue;
if (t.x == ex && t.y == ey) {
cout << "Yes";
return;
}
if (t.nengliang == 0)
continue;
if (ans[t.x][t.y]) {
if (t.nengliang > ans[t.x][t.y])
ans[t.x][t.y] = t.nengliang;
else
continue;
}
else
ans[t.x][t.y] = t.nengliang;
for (int i = 0; i < 4; i++) {
int xx = t.x + dx[i];
int yy = t.y + dy[i];
if (xx > 0 && xx <= h && yy > 0 && yy <= w && c[xx][yy] != '#') {
node d = t;
if (t.nengliang - 1 >= a[xx][yy])
d.nengliang--;
else
d.nengliang = a[xx][yy];
d.x = xx;
d.y = yy;
q.push(d);
}
}
}
cout << "No";
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> h >> w;
for (int i = 1; i <= h; i++) {
for (int j = 1; j <= w; j++) {
cin >> c[i][j];
if (c[i][j] == 'S') {
sx = i, sy = j;
}
if (c[i][j] == 'T') {
ex = i, ey = j;
}
}
}
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
int r, c, e;
cin >> r >> c >> e;
a[r][c] = e;
}
bfs();
return 0;
}