la solución del problema Luo Gu --P1126: Robot mover objetos pesados

temas relacionados

tema Enlace

Luo Valley, https://www.luogu.com.cn/problem/P1126 .

título Descripción

El robot se mueve Sociedad ( RMI) está ahora experimentando con robots de mercancías en movimiento. Forma del robot está en una esfera de 1,6 m de diámetro. En la fase de prueba, el robot se utiliza para la manipulación de mercancías en un compartimiento de almacenamiento. El compartimiento de almacenamiento es una cuadrícula de N × M, algunos obstáculos para una rejilla de inmuebles. Centro robots son siempre en la parrilla, por supuesto, el robot debe estar dentro del menor tiempo posible para transportar mercancías al lugar designado. El robot ha aceptado instrucciones: Paso 1 se mueve hacia adelante Creep(); paso 2 se mueve hacia adelante Walk(); Paso 3 se mueve hacia adelante Run(); gire a la izquierda Left(); derecho Right( ). El tiempo requerido para cada instrucción es de 1 segundo. Por favor, calcular el tiempo mínimo requerido para completar la tarea del robot.

Formato de entrada

Los dos primeros actos de números enteros positivos N, M (N, M ≤ 50), los siguientes N-línea es la configuración del compartimiento de almacenamiento, representa accesible 0, 1 indica que hay un obstáculo, separadas por un espacio entre los números. Luego hay cuatro líneas de enteros y una letra mayúscula, son el punto de partida y el punto de la esquina superior izquierda de las filas y columnas de la cuadrícula de destino, frente a la dirección (este E, Sur S, West W, Norte N) cuando se inicia, el número de y el número están separados por un espacio entre números y letras. La dirección de las caras extremas es arbitraria.

Formato de salida

Un entero que representa el tiempo mínimo requerido para que el robot completar tareas. Si no se puede alcanzar, de salida -1.

Ejemplo de entrada

9 10
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
7 2 2 7 S

Ejemplo de salida

12

tema de análisis

El análisis del significado de problemas

Un robot de una coordenada, requerida para conseguir un determinado fin. Laberinto es casi una cuestión común, añade algunas restricciones y métodos de medida no son los mismos.

1, no es la sub-dirección. Ese robot sólo puede ser movido a la dirección de la corriente.

2, la instrucción robot:Creep、Walk、Run、Left、Right。

3, hay un tamaño robot. Título nos dice que los robots tienen un diámetro de 1,6 m, que es tener en cuenta este factor. Se refieren a las figuras, se puede observar, el mapa es una ubicación de obstáculos, que los datos es 1, el robot no es obstáculo cuatro semanas para ir. Debido a que sólo 1M cada tamaño de la cuadrícula, el robot tiene un diámetro de 1,6 m. Hay un laberinto robots borde no pueden ir.

análisis de los datos de la muestra

No hay nada que. Omitirlo.

programación de las ideas

Aplicar una plantilla a un recorrido BFS estándar.

detalles de los códigos

Cómo definir la dirección?

1, utilizo C ++ tipos enum se definen como sigue:

enum DIR {
	//方向定义 
	EAST = 0,
	SOUTH,
	WEST,
	NORTH
};

El uso de enumeración sólo aumentó la legibilidad del código, el otro sin huevos.

2, la coordenada definida en la dirección necesaria para aumentar la definición. Se define como sigue:

struct POS {
	int x, y;//坐标
	int dir;//方向
	int dis;//距离 
	
};

¿Cómo describir la instrucción del robot?

De todos modos, pensé que lo que puede ser la descripción normalizada. Tenía el más simple de los métodos, se describe uno por uno para que el comando robot. Pseudo-código de la siguiente manera:

处理走路的3中方法
处理左转
处理右转

código de referencia AC

#include <cstdio>
#include <queue>

enum DIR {
	//方向定义 
	EAST = 0,
	SOUTH,
	WEST,
	NORTH
};

struct POS {
	int x, y;//坐标
	int dir;//方向
	int dis;//距离 
	
};

const int MAXN = 54;
struct MAZE {
	int row, col;//长宽 
	int x1, y1;//起点 
	int x2, y2;//终点
	int map[MAXN][MAXN];//迷宫数据
	bool visit[MAXN][MAXN][4];//访问性 
	int dir;
};

int bfs(MAZE &maze);

int main() {
	MAZE maze={};
	scanf("%d %d", &maze.row, &maze.col);
	
	int i, j;
	for (i=1; i<=maze.row; i++) {
		for (j=1; j<=maze.col; j++) {
			scanf("%d", &maze.map[i][j]);
			//注意机器人体积 
			if (maze.map[i][j]==1) {
				maze.map[i-1][j]=1;
				maze.map[i][j-1]=1;
				maze.map[i-1][j-1]=1;
			}
		}
	}
	
	char dir;
	scanf("%d %d %d %d %c", &maze.x1, &maze.y1, &maze.x2, &maze.y2, &dir);
	if (dir=='S') {
		maze.dir = SOUTH;
	} else if (dir=='W') {
		maze.dir = WEST;
	} else if (dir == 'N') {
		maze.dir = NORTH;
	} else {
		maze.dir = EAST;
	}
	
	//特别处理 
	if (maze.x2<1||maze.x2>=maze.row||maze.y2<1||maze.y2>=maze.col||maze.map[maze.x2][maze.y2]==1) {
		printf("-1\n");
		return 0;
	}
	
	printf("%d\n", bfs(maze));
	
	return 0;
}

int bfs(MAZE &maze) {
	std::queue<POS> q;
	
	//起点
	POS cur;
	cur.x   = maze.x1;
	cur.y   = maze.y1; 
	cur.dir = maze.dir;
	cur.dis = 0;
	q.push(cur);
	maze.visit[maze.x1][maze.y1][maze.dir] = true;
	
	//开始遍历 
	POS next;
	const int dx[4] = {0,1,0,-1};
	const int dy[4] = {1,0,-1,0};
	//const int dx[4] = {1,0,-1,0};
	//const int dy[4] = {0,1,0,-1};

	int i;
	while (q.empty()!=true) {
		cur = q.front();
		q.pop();
		
		//判断是否终点
		if (cur.x==maze.x2&&cur.y==maze.y2) {
			return cur.dis;
		}
		
		//开始走路
		for (i=1; i<=3; i++) {
			next.x = cur.x + dx[cur.dir]*i;
			next.y = cur.y + dy[cur.dir]*i;
			
			//判断是否在迷宫内
			if (next.x<1||next.x>=maze.row||next.y<1||next.y>=maze.col||maze.map[next.x][next.y]==1)  {
				break;
			} else if (maze.visit[next.x][next.y][cur.dir]==false) {
				maze.visit[next.x][next.y][cur.dir] = true;
				next.dis = cur.dis + 1;
				next.dir = cur.dir;
				q.push(next);
			}
		}
		
		//左转
		next.x = cur.x;
		next.y = cur.y;
		next.dir = cur.dir - 1;
		if (next.dir==-1) {
			next.dir = NORTH;
		}
		if (maze.visit[next.x][next.y][next.dir]==false) {
			maze.visit[next.x][next.y][next.dir] = true;
			next.dis = cur.dis + 1;
			q.push(next);
		}
		
		//右转 
		next.dir = cur.dir + 1;
		if (next.dir==4) {
			next.dir = EAST;
		}
		if (maze.visit[next.x][next.y][next.dir]==false) {
			maze.visit[next.x][next.y][next.dir] = true;
			next.dis = cur.dis + 1;
			q.push(next);
		}
	}
	
	return -1;
}
Publicados 223 artículos originales · ganado elogios 232 · Vistas 1,06 millones +

Supongo que te gusta

Origin blog.csdn.net/justidle/article/details/104773915
Recomendado
Clasificación