upc caminhada labirinto bfs

Percorrendo o labirinto
Limite de tempo: 1 segundo Limite de memória: 128 MB

Título Descrição O
Pcf maligno mantém KeineDuck em um labirinto! KeineDuck deve encontrar um caminho para a saída.
Por conveniência, descrevemos o labirinto como uma grade de n linhas e colunas M. Cada grade na grade possui um caractere especial:
• # indica que esta é uma parede e não pode passar.
• @: localização atual do KeineDuck.
• =: Saída do labirinto.
• Letra A Letra Z: Teleportadores, eles sempre aparecem em pares. Se KeineDuck caminhar até um dos teletransportadores, ela se teleportará para o outro teletransportador imediatamente.
Suponha que o KeineDuck consuma uma unidade de tempo a cada vez que ela se move.Agora, ela quer saber quanto tempo leva para chegar à saída.
Digite
dois números inteiros n, m na primeira linha, que representam o número de linhas e colunas.
Próximas n linhas, m caracteres por linha, o conteúdo específico, consulte a descrição do título. Um número inteiro é
emitido
, representando o tempo mínimo.
Em particular, se não houver caminho para a saída, -1 será exibido.
Entrada de amostra Cópia
5 6
### = ##
# .W. ##
#. ####
#. @ W ##

Saída de amostra Prompt de cópia
3
A
amostra explica que o
KeineDuck primeiro move um passo para a esquerda e o transfere para outro W.
KeineDuck deu mais um passo para a direita e um passo até o fim.
Um total de 3s foi usado.
Para 10% dos dados, n = m = 2.
Para outros 40% dos dados, não há dispositivo de transmissão.
Para os outros 20% dos dados, há apenas um par de dispositivos de transmissão.
Para 100% de dados, existem no máximo 26 pares de dispositivos de transmissão, n, m ≤ 300.

A idéia é fornecer uma matriz e, em seguida, encontrar a menor distância entre o ponto inicial e o ponto final.
Parece muito simples. . Eu não pensei muito no começo, primeiro WA. Vamos pensar cuidadosamente sobre o portal pode ser usado duas vezes, mas cada ponto só pode ser percorrido uma vez após a marcação do caminho bfs tradicional. Então, eu quero pré-processar a distância até o portal que pode ser alcançado e criar um bfs de várias fontes. O método de processamento é complicado e tem muitos detalhes. Demora muito tempo para escrever e requer dois bfs e não pode executar o TLE em 91, portanto Você precisa mudar um. Eu não posso pensar nisso agora marcar o caminho, gravar diretamente a distância a cada ponto, de modo que o cargo pode expandir o estado condições 's são alteradas quando o número atual etapa é menor do que o número de passos para chegar a este ponto antes, ele pode ser atualizado a este ponto A distância para outros pontos . Parece um pouco com dijkstra?
Na verdade, não é tão difícil.Eu acho problemático.O código ainda é muito simples. .

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#define X first
#define Y second
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

const int N=310,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n,m;
int ex,ey,cnt[N][N];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
char mp[N][N];
vector<PII>v[N];

struct Node
{
	int x,y;
	int step;
};

bool check(int x,int y)
{
	if(mp[x][y]=='#'||x<1||x>n||y<1||y>m)
		return true;
	return false;
}

void bfs(int x,int y)
{
	queue<Node>q;
	q.push({x,y,0});
	
	while(q.size())
	{
		Node t=q.front();
		q.pop();
		
		int s=t.step+1;
		
		if(cnt[ex][ey]!=INF) return;
		
		for(int i=0;i<4;i++)
		{
			int dx=t.x+dir[i][0];
			int dy=t.y+dir[i][1];
			
			if(check(dx,dy))
				continue;
			
			if(isalpha(mp[dx][dy]))//传送到相应位置 
			{
				char ch=mp[dx][dy];
				
				int x1=v[ch][0].X,y1=v[ch][0].Y;
				int x2=v[ch][1].X,y2=v[ch][1].Y;
				
				if(dx==x1&&dy==y1)
					dx=x2,dy=y2;
				else dx=x1,dy=y1;
			}
			
			if(s<cnt[dx][dy])
			{
				cnt[dx][dy]=s;
				q.push({dx,dy,s});
			}
		}
	}
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);

	memset(cnt,0x3f,sizeof cnt);

	int x,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",mp[i]+1);
		for(int j=1;j<=m;j++)
			if(mp[i][j]=='@')
				x=i,y=j;
			else if(mp[i][j]=='=')
				ex=i,ey=j;
			else if(mp[i][j]!='.'&&mp[i][j]!='#')
				v[mp[i][j]].push_back({i,j});
	}

	bfs(x,y);

	if(cnt[ex][ey]==INF) puts("-1");
	else printf("%d\n",cnt[ex][ey]);



	return 0;
}










Publicado 43 artigos originais · Gosto1 · Visitas 1538

Acho que você gosta

Origin blog.csdn.net/DaNIelLAk/article/details/105605763
Recomendado
Clasificación