OJ

[BOJ] 1726 로봇 (JAVA)

P3PP4 2022. 12. 26. 11:32

https://www.acmicpc.net/problem/1726

 

1726번: 로봇

많은 공장에서 로봇이 이용되고 있다. 우리 월드 공장의 로봇은 바라보는 방향으로 궤도를 따라 움직이며, 움직이는 방향은 동, 서, 남, 북 가운데 하나이다. 로봇의 이동을 제어하는 명령어는

www.acmicpc.net

BFS로 해결할 수 있는 문제입니다.

                st = new StringTokenizer(br.readLine(), " ");
                sr = Integer.parseInt(st.nextToken());
                sc = Integer.parseInt(st.nextToken());
                sd = Integer.parseInt(st.nextToken());
                if(sd == 2) sd = 3;
                else if(sd == 3) sd = 2;
                else if(sd == 4) sd = 0;
                st = new StringTokenizer(br.readLine(), " ");
                er = Integer.parseInt(st.nextToken());
                ec = Integer.parseInt(st.nextToken());
                ed = Integer.parseInt(st.nextToken());
                if(ed == 2) ed = 3;
                else if(ed == 3) ed = 2;
                else if(ed == 4) ed = 0;

로봇의 방향에 대해서 저에게 편한 방법으로 풀려고 값을 조금 수정했습니다.

동 서 남 북 -> 북 동 남 서(시계방향)

 

		for (int i = 0; i < N + 2; i++) {
			map[i][0] = map[i][M + 1] = 1;
		}
		for (int i = 0; i < M + 2; i++) {
			map[0][i] = map[N + 1][i] = 1;
		}

또한 배열의 테두리를 1로 채웠습니다.

 

이문제에서 중요하다고 생각하는 부분

1. 앞으로 전진할 때 벽이 나오면 그 다음 칸은 보지 않고 넘긴다.

2. 행, 열 위치에 추가로 방향에 대한 visited 체크를 한다.

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	static int N, M, sr, sc, sd, er, ec, ed;
	static int[][] map;
	static int[][][] visited;
	static int[] dr = { -1,  0,  1,  0 };
	static int[] dc = {  0,  1,  0, -1 };
	
	public static void main(String[] args) throws Exception {
		
		st = new StringTokenizer(br.readLine(), " ");
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		map = new int[N + 2][M + 2];
		visited = new int[4][N + 2][M + 2];
		for (int i = 0; i < N + 2; i++) {
			map[i][0] = map[i][M + 1] = 1;
		}
		for (int i = 0; i < M + 2; i++) {
			map[0][i] = map[N + 1][i] = 1;
		}
		for (int i = 1; i <= N; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j = 1; j <= M; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		st = new StringTokenizer(br.readLine(), " ");
		sr = Integer.parseInt(st.nextToken());
		sc = Integer.parseInt(st.nextToken());
		sd = Integer.parseInt(st.nextToken());
		if(sd == 2) sd = 3;
		else if(sd == 3) sd = 2;
		else if(sd == 4) sd = 0;
		st = new StringTokenizer(br.readLine(), " ");
		er = Integer.parseInt(st.nextToken());
		ec = Integer.parseInt(st.nextToken());
		ed = Integer.parseInt(st.nextToken());
		if(ed == 2) ed = 3;
		else if(ed == 3) ed = 2;
		else if(ed == 4) ed = 0;
		// end of input
		
		Queue<Robot> q = new LinkedList<>();
		q.offer(new Robot(sr, sc, sd));
		visited[sd][sr][sc] = 1;
		
		while(!q.isEmpty()) {
			
			Robot r = q.poll();
			
			if(r.r == er && r.c == ec && r.d == ed) {
				System.out.print(visited[ed][er][ec] - 1);
				return;
			}
			
			// 오른쪽 회전
			if(visited[(r.d + 1) % 4][r.r][r.c] == 0) {
				q.offer(new Robot(r.r, r.c, (r.d + 1) % 4));
				visited[(r.d + 1) % 4][r.r][r.c] = visited[r.d][r.r][r.c] + 1;
			}
			// 왼쪽 회전
			if(visited[r.d - 1 < 0 ? r.d + 3 : r.d - 1][r.r][r.c] == 0) {
				q.offer(new Robot(r.r, r.c, r.d - 1 < 0 ? r.d + 3 : r.d - 1));
				visited[r.d - 1 < 0 ? r.d + 3 : r.d - 1][r.r][r.c] = visited[r.d][r.r][r.c] + 1;
			}
			// 앞으로 i칸 전진
			for (int i = 1; i <= 3; i++) {
				
				int nr = r.r + dr[r.d] * i; 
				int nc = r.c + dc[r.d] * i;
				
				if(visited[r.d][nr][nc] == 0) {
					
					if(map[nr][nc] == 1) break;
					
					q.offer(new Robot(nr, nc, r.d));
					visited[r.d][nr][nc] = visited[r.d][r.r][r.c] + 1;
					
				}
				
			}
			
		}
		
	}
	
	static class Robot {
		
		int r, c, d;

		public Robot(int r, int c, int d) {

			this.r = r;
			this.c = c;
			this.d = d;
			
		}
		
	}
	
}