Comer serpientes

Título Greedy Snake-Aprendizaje comparativo de dfs y bfs (apto para principiantes)

Dirección del título codicioso
serpiente enlace
https://ac.nowcoder.com/acm/contest/9986/I
Enlace: https://ac.nowcoder.com/acm/contest/9986/I
Fuente: Niuke.com

Descripción del título El
juego de serpientes en crecimiento infinito:

En un laberinto de n * m, hay una pequeña serpiente. Hay muchas paredes en el mapa. El desdichado interrogador está representado por "#", y el camino que se puede tomar está representado por ".". La serpiente nació en un lugar aleatorio. En la parte superior, el punto de generación se representa como "S", y el punto final al que quiere llegar se representa como "E". La pequeña serpiente tiene una habilidad extraña. Cada vez que camina, aumenta por uno. Es decir, después de que camina un cuadrado, la cola no se retrae.

La pequeña serpiente quiere saber cómo llega a donde quiere ir, por favor ayúdelo.

PD: Cada cuadrícula tiene 1 metro de largo, las serpientes no pueden golpear la pared o morderse el propio cuerpo.
Descripción de entrada: la
primera línea: entrada N, M;

Segunda línea: Ingrese las coordenadas Xs, Ys de S y Xe, Ye de E;

Las siguientes N líneas:

Ingrese M números para cada línea para describir la situación de cada línea.

Descripción de
salida : salida un número, la distancia más corta (unidad: cm) para que la serpiente alcance el punto final, si no se puede alcanzar, salida -1
ejemplo 1
entrada
copia
3 3
1 1 3 3.
#
.. #.
copia de
salida 400 ejemplo 2 copia de entrada 5 5 1 1 5 5 … ### . #… . #. # .. #. #. … #. Copia de salida 1400 Nota: Para datos al 100%: 1 \ le n, m \ le 1001≤n, m≤100, para garantizar que el punto de partida no sea una valla.
















Ideas
* 1. * Se pueden resolver tanto bfs como dfs, pero diferentes formas encontrarán el mismo problema: cómo expresar la distancia, cómo encontrar la distancia más cercana
* 2. * Para bfs, registra los lugares a los que se puede mover cada tiempo, es decir, diga un punto a un punto que se puede mover, primero lo atravesará y luego irá, para que podamos cambiar la matriz vis (originalmente utilizada para registrar si ha caminado, para evitar moverse hacia adelante y hacia atrás) , y cámbielo para cambiar el punto en el registro. El dato de distancia, es decir, vis se obtiene moviendo unos pasos desde el punto de partida.
el código se muestra a continuación:

#include<bits/stdc++.h>
using namespace std;
const int M = 110;
int vis[110][110];
int m,n,xs,ys,ye,xe,ok; //初始数据 
char Map[110][110];
struct node{
    
    
	int xx;
	int yy; 
};//表示坐标 
int dx[4] = {
    
    -1,0,1,0};
int dy[4] = {
    
    0,-1,0,1};
void bfs(){
    
    
	queue<node> q;
	node beg,ll;//beg是将起点变成node的类型,不然queue不认识,见面就打架
				//ll也是转换,就是新得到出来的点 转换,详情往下看 
	beg.xx=xs;
	beg.yy=ys;
	q.push(beg);
	vis[xs][ys] = 0;
	while(!q.empty()){
    
    
		node top = q.front();
		q.pop();
		if(top.xx==xe&&top.yy==ye) {
    
    
			ok = 1;
			return ;
		}
		for(int i = 0;i<4;i++){
    
    
			int xx = top.xx+dx[i];
			int yy = top.yy+dy[i];
			if(xx>=1&&xx<=n&&yy>=1&&yy<=m){
    
    
				if(vis[xx][yy] == -1&&Map[xx][yy]!='#'){
    
    
				vis[xx][yy] = vis[top.xx][top.yy]+1; //与普通bfs区别 就在这,没错,理解这里就okk了。 
				ll.xx = xx;
				ll.yy = yy;
				q.push(ll);
				}
			}
		}	
	}
	
}
int main(){
    
    
	scanf("%d%d%d%d%d%d",&n,&m,&xs,&ys,&xe,&ye);
	for(int i = 1;i<=n;i++){
    
    
		scanf(" ");
		for(int j = 1;j<=m;j++)
		scanf("%c",&Map[i][j]);
	}
	memset(vis,-1,sizeof vis);
	bfs();
	if(!ok) cout<<-1<<endl;
	else
	cout<<(vis[xe][ye])*100<<endl;
	return 0;
}

Oh, he dicho tanto, de hecho, siempre que entiendas vis [xx] [yy] = vis [top.xx] [top.yy] +1, puedes entender.
* 3. * dfs debe prestar atención a una ruta que puede ser recorrida por otro esquema, es decir, un punto puede usarse varias veces, por lo que cuando se atraviesa el punto, aún necesita salir.
el código se muestra a continuación

#include<bits/stdc++.h>
using namespace std;
int n,m,xs,ys,xe,ye; //初始读入 
const int INF  = 0x4f4f4f4f; //设置最大值 
int vis[110][110];  //记录是否走过
char Map[110][110]; 
struct node{
    
    
	int xx,yy;
	bool operator==(const node& nw){
    
    	//定义 相等 
		return (nw.xx==xx&&nw.yy==yy);  
	}
}be,en; //起点和终点 
int maxs = INF,ok;
int dx[4]={
    
    0,1,0,-1};
int dy[4]={
    
    1,0,-1,0};
void dfs(node t,int dis){
    
    
	if(t == en){
    
    
		maxs = min(dis,maxs);
		ok = 1; 
	}
	int xx,yy;
	vis[t.xx][t.yy] = 1; 
	for(int i = 0;i<4;i++){
    
    
		xx = t.xx+dx[i];
		yy = t.yy+dy[i];
		if(xx>0&&xx<=n&&yy>0&&yy<=m&&vis[xx][yy]==0&&Map[xx][yy]!='#'){
    
    
			node go;
			go.xx=xx;
			go.yy=yy;
			vis[xx][yy] = 1; 
			dfs(go,dis+1);
			//与简单的dfs区别就是这了,没错!!! 
			vis[xx][yy] = 0; //出来后表示回去,因此这条路也就不能算走过了 
		}
	}

}
int main(){
    
    
	scanf("%d%d",&n,&m);
	scanf("%d%d%d%d",&xs,&ys,&xe,&ye);
	be.xx = xs;
	be.yy = ys;
	en.xx = xe;
	en.yy = ye;
	for(int i = 1;i<=n;i++){
    
    
		scanf(" ");
		for(int j = 1;j<=m;j++){
    
    
			scanf("%c",&Map[i][j]);
		}
	}
	dfs(be,0);
	
	if(ok)
	cout<<maxs*100<<endl;
	else cout<<-1<<endl;
	return 0;
} 

Fui a hacerme esperar la comparación resumida
de los dos códigos anteriores, encontrará, bfs siempre que la primera vez encuentre la salida, esa es la distancia más corta, mientras aún ejecuta dfs foto completa, los métodos de optimización pueden ser lo que hice no espere. . .
Con todo, la sugerencia es que es mejor y más conveniente usar bfs cuando se recorre la distancia más corta.

Supongo que te gusta

Origin blog.csdn.net/eatkeyborad/article/details/114107521
Recomendado
Clasificación