1. 문제
https://www.acmicpc.net/problem/1726
1726번: 로봇
많은 공장에서 로봇이 이용되고 있다. 우리 월드 공장의 로봇은 바라보는 방향으로 궤도를 따라 움직이며, 움직이는 방향은 동, 서, 남, 북 가운데 하나이다. 로봇의 이동을 제어하는 명령어는
www.acmicpc.net
생각없이 풀기 좋은 시뮬 문제
생긴게 삼성문제 같은데 올림피아드 문제다
2. 접근방법
최소 횟수로 출발점에서 도착점까지 도착하는 문제
고려해야 할 사항들
1. 회전도 하나의 횟수로 친다
2. 회전은 왼쪽 오른쪽만 가능
3. visit처리 안하면 메모리 터짐 ( [방향][row][col]로 3차원 배열로 설정 )
4. 전진은 한 횟수에 1,2,3칸 가능
4-1. 전진 1이 불가능이면 2,3도 불가능
4-2. 전진 1이 방문했더라도 2,3을 갈 수 있음.
일반적인 bfs탐색처럼 풀이하되 분기가
1. 왼쪽 방향 변경
2. 오른쪽 방향 변경
3. 전진 1,2,3칸 (예외처리를 break, continue 위 고려사항 맞게 적절히)
인 것만 생각하고 풀이하면 된다.
방향이 특이하게 동서남북 순서로 주어진다.
0,1,2,3 으로 생각하고
왼쪽 오른쪽 방향설정시 아이디어로
현재방향이 0 or 1이면 2,3 으로 방향변경
현재방향이 2 or 3이면 0,1 으로 방향변경 해주면 된다.
3. 자바 코드
package Gold;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class G4_1726로봇 {
static class node {
int row;
int col;
int dir;
public node(int row, int col, int dir) {
this.row = row;
this.col = col;
this.dir = dir;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int map[][] = new int[N][M];
for (int i = 0; i < N; i++)
map[i] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int start[] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int end[] = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
for (int i = 0; i < 3; i++) { // 인덱스 맞추기
start[i] -= 1;
end[i] -= 1;
}
int dr[] = new int[] { 0, 0, 1, -1 }; //동서남북
int dc[] = new int[] { 1, -1, 0, 0 };
boolean visit[][][] = new boolean[4][N][M]; // dir row col
visit[start[2]][start[0]][start[1]] = true;
Queue<node> que = new LinkedList<node>();
que.add(new node(start[0], start[1], start[2]));
int cnt = 0;
while (!que.isEmpty()) {
int size = que.size();
while (size-- != 0) {
node now = que.poll();
if (now.row == end[0] && now.col == end[1] && now.dir == end[2]) {
System.out.println(cnt);
return;
}
// 왼쪽 오른쪽 직진(1,2,3)
int left = now.dir > 1 ? 0 : 2;
int right = now.dir > 1 ? 1 : 3;
if (!visit[left][now.row][now.col]) {
que.add(new node(now.row, now.col, left));
visit[left][now.row][now.col] = true;
}
if (!visit[right][now.row][now.col]) {
que.add(new node(now.row, now.col, right));
visit[right][now.row][now.col] = true;
}
for (int i = 1; i <= 3; i++) {
int row = now.row + dr[now.dir] * i;
int col = now.col + dc[now.dir] * i;
if (row >= N || col >= M || row < 0 || col < 0)
break;
if (map[row][col] == 1)
break;
if (visit[now.dir][row][col])
continue;
que.add(new node(row, col, now.dir));
visit[now.dir][row][col] = true;
}
}
cnt++;
}
}
}
4. 마치며
전진 중간에 break이 들어가야 하는 조건이 재밌었다.
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 2631 줄세우기 (0) | 2021.11.25 |
---|---|
[백준] 5557 1학년 (0) | 2021.11.23 |
[백준] 9084 동전 (0) | 2021.11.09 |
[백준] 11000 강의실 배정 (0) | 2021.11.04 |
[백준] 2357 최솟값과 최댓값 (0) | 2021.11.02 |