找朋友(bfs常錯!!)

cn是大帅哥886發表於2024-08-20
第1題 找朋友 檢視測評資料資訊

有一個H行和W列的網格。(i,j)表示位於從上往下第i行和從左往右第j列的單元格。每個單元格有字元A(i,j):

(1)A(i,j)=’.’表示空單元格

(2)A(i,j)=’#’表示一個障礙物

(3)A(i,j)=’S’表示起點

(4)A(i,j)=’T’表示終點

現在Jane可以透過消耗1能量從當前單元格移動到上下左右的空單元格。如果能量為0,他就無法移動,也無法離開網格。網格中有N種藥。第i種藥位於空格(R,C)處,可以用來把能量變成E[i]。注意,能量並不一定會增加。他可以在當前格子中使用藥物。使用過的藥物會消失。Jane以0的能量從起點開始,並希望達到終點。請判斷這是否可行。如果可以輸出“Yes”,否則輸出“No”。

輸入格式

第一行兩個整數H,W

接下來H行,每行W個字元,字元可能是’.’,’#’,’S’,’T’

接下來一行一個整數N

接下來N行,每行三個整數R,C,E,表示第R行第C列有一個能把能量變為E的藥。

1<=H,W<=200,1<=N<=300,1<=R<=H,1<=C<=W,1<=E<=H*W

輸出格式

“Yes”或“No”

輸入/輸出例子1

輸入:

4 4

S...

#..#

#...

..#T

4

1 1 3

1 3 5

3 2 1

2 3 1

輸出:

Yes

輸入/輸出例子2

輸入:

2 2

S.

T.

1

1 2 4

輸出:

No

樣例解釋

不是?明明會做,每次都寫錯了

只強調一點

記錄最優答案,如果當前搜尋的答案不優於最優答案,就跳過,而不是用vis!以後別用那啥vis判斷>=1000這種劣質操作了!!!!!!

#include <bits/stdc++.h>
using namespace std;
const int N=205;

struct node
{
	int x, y, u;
}s, t;
int n, m, f[N][N], g, x, y, a[N][N], dis[N][N];
int dx[]={0, 0, 1, -1}, dy[]={1, -1, 0, 0};
char c[N][N];
queue<node> q;
bool bfs()
{
	memset(dis, 0, sizeof dis);
	q.push({s.x, s.y, a[s.x][s.y]});
	while (!q.empty())
	{
		int x=q.front().x, y=q.front().y, u=q.front().u;
		q.pop();
		
		if (x==t.x && y==t.y && max(u, dis[x][y])>=0) return 1;
		if (u<=0) continue;
		
		if (dis[x][y]>=u) continue;
		dis[x][y]=u;
		
		for (int i=0; i<4; i++)
		{
			int nx=x+dx[i], ny=y+dy[i];
			if (nx>=1 && nx<=n && ny>=1 && ny<=m && c[nx][ny]!='#')
			{
				if (a[nx][ny]>u-1) q.push({nx, ny, a[nx][ny]}), a[nx][ny]=0;
				else q.push({nx, ny, u-1});
			}
		}
	}
	
	return 0;
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) scanf("%s", c[i]+1);
	
	scanf("%d", &g);
	while (g--)
	{
		scanf("%d%d", &x, &y);
		scanf("%d", &a[x][y]);
	}
	
	for (int i=1; i<=n; i++)
		for (int j=1; j<=m; j++)
		{
			if (c[i][j]=='S') s.x=i, s.y=j;
			if (c[i][j]=='T') t.x=i, t.y=j;
		}
	
	if (bfs()) printf("Yes");
	else printf("No");
	return 0;
}
/*
S.5.
#.1#
#1..
..#T

*/

  

相關文章