Luo Gu problem solution --P1126: Robot moving heavy objects

Related topics

Topic Link

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

Title Description

The robot moves Society ( RMI) is now experimenting with robots moving goods. Shape of the robot is in a 1.6 m diameter sphere. In the test phase, the robot is used for handling of goods in a storage compartment. The storage compartment is a grid of N × M, some obstacles to an immovable grid. Center robots are always on the grid, of course, the robot must be within the shortest possible time to carry goods to the designated place. The robot has accepted instructions: Step 1 moves forward Creep( ); step 2 moves forward Walk( ); Step 3 is moved forward Run( ); turn left Left( ); right Right( ). Time required for each instruction is 1 second. Please calculate the minimum time required to complete the robot task.

Input Format

The first two acts of positive integers N, M (N, M ≤ 50), the following N-line is the configuration of the storage compartment, accessible represents 0, 1 indicates there is an obstacle, separated by a space between the numbers. Then there are four integer line and a capital letter, are the starting point and the destination point of the upper left corner of the grid rows and columns, facing the direction (east E, South S, West W, North N) when starting, the number of and number are separated by a space between numbers and letters. The direction of the end faces is arbitrary.

Output Format

An integer representing the minimum time required for the robot to complete tasks. If you can not reach, output -1.

SAMPLE INPUT

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

Sample Output

12

Topic analysis

Analysis of the meaning of problems

A robot from a coordinate, required to achieve a certain end. Maze is almost a standard issue, adds some restrictions and move methods are not the same.

1, there is the sub-direction. That robot can only be moved to the current direction.

2, the robot instruction:Creep、Walk、Run、Left、Right。

3, there is a robot size. Title tells us that robots have a diameter of 1.6m, that is to consider this factor. Refer to the figures, it can be seen, the map is a location of obstacles, that data is 1, the robot is not obstacle four weeks to go. Because only 1m each grid size, the robot has a diameter of 1.6m. There is a maze edge robots can not go.

Sample data analysis

Nothing to write. Omit it.

Programming ideas

Apply a template to a standard BFS traversal.

Code details

How to define direction?

1, I use C ++ enum types are defined as follows:

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

Use enum only increased the readability of the code, the other with no eggs.

2, the coordinate defined in the direction necessary to increase the definition. It is defined as follows:

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

How to describe the robot instruction?

Anyway, I thought out what can be normalized description. Had the most simplest of methods, described one by one so that the robot command. Pseudo-code as follows:

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

AC reference code

#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;
}
Published 223 original articles · won praise 232 · Views 1.06 million +

Guess you like

Origin blog.csdn.net/justidle/article/details/104773915