牛客 Apppese走迷宫

带状态的广搜

题意:

输入

5 5
.w@..
.S#..
~w#..
.w..~
@w.~T

输出

18

备注:
1 n, m 100

思路:
char数组 g :存输入
d[ x ] [ y ] [ k ] 数组存:当状态是k时到位置(x,y)的步数
当前一开始先把初始点入队,将其d数组改为0。
之后循环遍历,如果当前的点是终点,直接返回终点的d数组值,即到终点的步数
如果当前是第一次到转换属性点,d[x] [y] [!k] = d[x] [y] [k] + 1,因为转换时间需要1秒,然后将转换后的状态加进队列。
判断可行性时,一共有四层。1️⃣是否在范围内2️⃣是否经过过3️⃣是否是障碍4️⃣是否水塘或火坑与属性相反

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n,m;
char g[N][N];
int sx,sy,tx,ty;
int d[N][N][2];
int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};
struct node{
	int x,y,z;
};
int bfs(int x,int y){
	queue<node> q;
	q.push({x,y,0});
	d[x][y][0] = 0;
	while(q.size()){
		node top = q.front();q.pop();
		if(top.x == tx && top.y == ty)
			return d[tx][ty][top.z];
		if(g[top.x][top.y] == '@' && d[top.x][top.y][!top.z] == -1){
			d[top.x][top.y][!top.z] = d[top.x][top.y][top.z] + 1;
			q.push({top.x,top.y,!top.z});
		}
		for(int i=0;i<4;i++){
			int nowx = top.x + dx[i];
			int nowy = top.y + dy[i];
			if(nowx<1||nowx>n||nowy<1||nowy>m) continue;
			if(d[nowx][nowy][top.z]!=-1) continue;
			if(g[nowx][nowy] == '#') continue;
			if(top.z == 0 && g[nowx][nowy] == 'w' ||
				top.z == 1 && g[nowx][nowy] == '~') continue;
			
			d[nowx][nowy][top.z] = d[top.x][top.y][top.z] + 1;
			q.push({nowx,nowy,top.z});
			
		}
	}
	return -1;
}

int main(){
	memset(d,-1,sizeof d);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        getchar();
        scanf("%s",g[i]+1);
        for(int j=1;j<=m;j++){
        	if(g[i][j] == 'S'){
        		sx = i, sy = j;
			}
			if(g[i][j] == 'T'){
				tx = i, ty = j;
			}
		}
    }
    printf("%d\n",bfs(sx,sy));
    return 0;
}
posted @   Isaac233  阅读(45)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示