Skip to content

Commit 3fbe9c2

Browse files
committed
[Gold III] Title: 로봇, Time: 128 ms, Memory: 14960 KB -BaekjoonHub
1 parent 73abf7c commit 3fbe9c2

File tree

2 files changed

+167
-0
lines changed

2 files changed

+167
-0
lines changed

백준/Gold/1726. 로봇/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# [Gold III] 로봇 - 1726
2+
3+
[문제 링크](https://www.acmicpc.net/problem/1726)
4+
5+
### 성능 요약
6+
7+
메모리: 14960 KB, 시간: 128 ms
8+
9+
### 분류
10+
11+
너비 우선 탐색, 그래프 이론, 그래프 탐색
12+
13+
### 제출 일자
14+
15+
2025년 3월 15일 02:14:38
16+
17+
### 문제 설명
18+
19+
<p>많은 공장에서 로봇이 이용되고 있다. 우리 월드 공장의 로봇은 바라보는 방향으로 궤도를 따라 움직이며, 움직이는 방향은 동, 서, 남, 북 가운데 하나이다. 로봇의 이동을 제어하는 명령어는 다음과 같이 두 가지이다.</p>
20+
21+
<ul>
22+
<li>명령 1. Go k: k는 1, 2 또는 3일 수 있다. 현재 향하고 있는 방향으로 k칸 만큼 움직인다.</li>
23+
<li>명령 2. Turn dir: dir은 left 또는 right 이며, 각각 왼쪽 또는 오른쪽으로 90° 회전한다.</li>
24+
</ul>
25+
26+
<p>공장 내 궤도가 설치되어 있는 상태가 아래와 같이 0과 1로 이루어진 직사각형 모양으로 로봇에게 입력된다. 0은 궤도가 깔려 있어 로봇이 갈 수 있는 지점이고, 1은 궤도가 없어 로봇이 갈 수 없는 지점이다. 로봇이 (4, 2) 지점에서 남쪽을 향하고 있을 때, 이 로봇을 (2, 4) 지점에서 동쪽으로 향하도록 이동시키는 것은 아래와 같이 9번의 명령으로 가능하다.</p>
27+
28+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/6d410e6d-cced-4f83-b9b8-75404e77b2b9/-/preview/" style="width: 276px; height: 259px;"></p>
29+
30+
<p>로봇의 현재 위치와 바라보는 방향이 주어졌을 때, 로봇을 원하는 위치로 이동시키고, 원하는 방향으로 바라보도록 하는데 최소 몇 번의 명령이 필요한지 구하는 프로그램을 작성하시오.</p>
31+
32+
### 입력
33+
34+
<p>첫째 줄에 공장 내 궤도 설치 상태를 나타내는 직사각형의 세로 길이 M과 가로 길이 N이 빈칸을 사이에 두고 주어진다. 이때 M과 N은 둘 다 100이하의 자연수이다. 이어 M줄에 걸쳐 한 줄에 N개씩 각 지점의 궤도 설치 상태를 나타내는 숫자 0 또는 1이 빈칸을 사이에 두고 주어진다. 다음 줄에는 로봇의 출발 지점의 위치 (행과 열의 번호)와 바라보는 방향이 빈칸을 사이에 두고 주어진다. 마지막 줄에는 로봇의 도착 지점의 위치 (행과 열의 번호)와 바라보는 방향이 빈칸을 사이에 두고 주어진다. 방향은 동쪽이 1, 서쪽이 2, 남쪽이 3, 북쪽이 4로 주어진다. 출발지점에서 도착지점까지는 항상 이동이 가능하다.</p>
35+
36+
### 출력
37+
38+
<p>첫째 줄에 로봇을 도착 지점에 원하는 방향으로 이동시키는데 필요한 최소 명령 횟수를 출력한다.</p>
39+
+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
5+
public class Main {
6+
//다익스트라 탐색할 때 로봇 정보
7+
static class Info implements Comparable<Info>{
8+
//r : y, c : x
9+
//cnt : 명령 횟수, dir : 방향
10+
int r, c, cnt, dir;
11+
Info(int r, int c, int cnt, int dir){
12+
this.r = r;
13+
this.c = c;
14+
this.cnt = cnt;
15+
this.dir = dir;
16+
}
17+
//명령 횟수 기준 오름차순 정렬
18+
@Override
19+
public int compareTo(Info o){
20+
return this.cnt - o.cnt;
21+
}
22+
}
23+
public static void main(String[] args) throws IOException {
24+
//입력값 처리하는 BufferedReader
25+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
26+
//결과값 출력하는 BufferedWriter
27+
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
28+
StringTokenizer st = new StringTokenizer(br.readLine()," ");
29+
int N = Integer.parseInt(st.nextToken());
30+
int M = Integer.parseInt(st.nextToken());
31+
int[][] map = new int[N][M];
32+
//공장 정보 저장
33+
for(int i=0;i<N;i++){
34+
st = new StringTokenizer(br.readLine()," ");
35+
for(int j=0;j<M;j++){
36+
map[i][j] = Integer.parseInt(st.nextToken());
37+
}
38+
}
39+
int[][] position = new int[2][3];
40+
//시작 위치, 도착 위치 정보 저장
41+
for(int i=0;i<2;i++){
42+
st = new StringTokenizer(br.readLine()," ");
43+
position[i][0] = Integer.parseInt(st.nextToken()) - 1;
44+
position[i][1] = Integer.parseInt(st.nextToken()) - 1;
45+
//{동, 서, 남, 북} -> { 북, 동, 남, 서 } 형식으로 변경
46+
position[i][2] = setDir(Integer.parseInt(st.nextToken()));
47+
}
48+
//다익스트라 탐색
49+
int result = bfs(map, position, N, M);
50+
//최소 명령 횟수 BufferedWriter 저장
51+
bw.write(String.valueOf(result));
52+
bw.flush(); //결과 출력
53+
bw.close();
54+
br.close();
55+
}
56+
//다익스트라를 통해서 최소 명령 횟수 탐색하는 함수
57+
static int bfs(int[][] map, int[][] position, int N, int M){
58+
PriorityQueue<Info> pq = new PriorityQueue<>();
59+
//북동남서 이동하는 변경 r, c의 값
60+
int[] dr = {-1, 0, 1, 0};
61+
int[] dc = {0 , 1, 0, -1};
62+
//방문 확인 배열
63+
boolean[][][] visited = new boolean[N][M][4];
64+
//시작 위치를 기준으로 정보 저장
65+
visited[position[0][0]][position[0][1]][position[0][2]] = true;
66+
pq.offer(new Info(position[0][0], position[0][1], 0, position[0][2]));
67+
//다익스트라 진행
68+
while(!pq.isEmpty()){
69+
Info cur = pq.poll();
70+
//도착 위치 도달 시
71+
if(cur.r == position[1][0] && cur.c == position[1][1] && cur.dir == position[1][2]){
72+
return cur.cnt;
73+
}
74+
//현재 방향으로 1, 2, 3칸 이동
75+
int nr = cur.r;
76+
int nc = cur.c;
77+
for(int i=1;i<=3;i++){
78+
nr += dr[cur.dir];
79+
nc += dc[cur.dir];
80+
//공장에 벗어나거나, 경로가 막힐 때
81+
if(!inSpace(nr, nc, N, M) || map[nr][nc] == 1){
82+
break;
83+
}
84+
//이미 방문한 공간일 때
85+
if(visited[nr][nc][cur.dir]){
86+
continue;
87+
}
88+
//전진!
89+
visited[nr][nc][cur.dir] = true;
90+
pq.offer(new Info(nr, nc, cur.cnt + 1, cur.dir));
91+
}
92+
93+
//오른쪽 회전
94+
int rd = (cur.dir + 1) % 4;
95+
if(!visited[cur.r][cur.c][rd]){
96+
visited[cur.r][cur.c][rd] = true;
97+
pq.offer(new Info(cur.r, cur.c, cur.cnt + 1, rd));
98+
}
99+
//왼쪽 회전
100+
int ld = (cur.dir - 1) < 0 ? 3 : cur.dir - 1;
101+
if(!visited[cur.r][cur.c][ld]){
102+
visited[cur.r][cur.c][ld] = true;
103+
pq.offer(new Info(cur.r, cur.c, cur.cnt + 1, ld));
104+
}
105+
}
106+
return 0;
107+
}
108+
//{동, 서, 남, 북} -> {북, 동, 남, 서} 변경 함수
109+
static int setDir(int dir){
110+
if(dir == 1){ //동 -> 동
111+
return 1;
112+
}else if(dir == 2){ //서 -> 동
113+
return 3;
114+
}else if(dir == 3){ // 남 -> 남
115+
return 2;
116+
}else{ //북 -> 서
117+
return 0;
118+
}
119+
}
120+
//이동하려는 칸이 공장에 존재하는지 확인하는 함수
121+
static boolean inSpace(int r, int c, int N, int M){
122+
if(r >= 0 && c >= 0 && r < N && c < M){
123+
return true;
124+
}
125+
return false;
126+
}
127+
}
128+

0 commit comments

Comments
 (0)