티스토리 뷰
https://www.acmicpc.net/problem/3987
3987번: 보이저 1호
첫째 줄에 시그널을 보내는 방향을 출력한다. (U: 위, R: 오른쪽, D: 아래, L: 왼쪽) 만약, 방향이 여러 가지가 존재한다면, U, R, D, L의 순서 중 앞서는 것을 출력한다. 둘째 줄에는 가장 긴 시간을 출
www.acmicpc.net
풀이
0) 방향이 존재하므로 3차원 방문체크배열을 만든다. isVisited[][][4]
1) 어떤 방향에서 어떤 행성(/ or \)을 만날때 방향이 어디로 바뀌는지 알면 된다.
2) URDL 을 0123 이라고 할 경우
2-1) / 행성을 지날경우 1032 로 바뀐다. => dir = dir^1
2-2) \행성을 지날경우 3210 으로 바뀐다. => dir = 3-dir
3) 모든 방향으로 시그널을 보내서
3-1) 밖으로 나가거나 (!isIn(r,c)) 블랙홀에 막힐때까지 (map[][] = 'C') 탐색을 한다. 탐색한 곳은 방문체크를 한다.
3-2) 만약 방문한 곳을 또 방문하게 된다면 무한루프를 돈다는 의미이다.
4) 결과 출력
주의사항
1) "만약, 방향이 여러 가지가 존재한다면, U, R, D, L의 순서 중 앞서는 것을 출력한다." => 반드시 방향은 위, 오른쪽, 아래, 왼쪽 순서여야 함.
2) Voyager 를 Voyger로 써서 왜 안되지 하고 30분 날렸다. 🧡✨ㅅㅂ💎🎇
package com.baekJoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.StringTokenizer;
public class BJ_S2_3987_보이저1호 {
static BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokens;
static int N,M, PR,PC, max = Integer.MIN_VALUE;
static char map[][], answer;
static boolean isVisited[][][];
public static void main(String[] args) throws NumberFormatException, IOException {
input = new BufferedReader(new StringReader(src));
tokens = new StringTokenizer(input.readLine());
N = Integer.parseInt(tokens.nextToken());
M = Integer.parseInt(tokens.nextToken());
map = new char[502][502];
isVisited = new boolean[502][502][4];
for(int r=0; r<N; r++) {
String line = input.readLine();
for(int c=0; c<M; c++) {
map[r][c] = line.charAt(c);
}
}
tokens = new StringTokenizer(input.readLine());
PR = Integer.parseInt(tokens.nextToken())-1;
PC = Integer.parseInt(tokens.nextToken())-1;
outer : for(int dir=0; dir<4; dir++) {
int cnt = 0;
isVisited = new boolean[N][M][4];
int nr = PR;
int nc = PC;
int curDir = dir;
while(true) {
cnt++;
if(!isVisited[nr][nc][curDir]) {
isVisited[nr][nc][curDir] = true;
}else {
answer = d[dir];
max = Integer.MAX_VALUE;
break outer;
}
nr += dr[curDir];
nc += dc[curDir];
if(!isIn(nr, nc) || map[nr][nc] == 'C') {
if(max < cnt) {
answer = d[dir];
max = cnt;
}
break;
}
if(map[nr][nc] == '/') {
curDir = curDir ^ 1;
}else if(map[nr][nc] == '\\') {
curDir = 3-curDir;
}
}
}
System.out.println(answer);
if(max == Integer.MAX_VALUE) {
System.out.println("Voyger");
}else {
System.out.println(max);
}
}
static char d[] = {'U', 'R', 'D', 'L'};
static int dr[] = {-1,0,1,0}; // 상, 우, 하, 좌
static int dc[] = {0,1,0,-1};
static boolean isIn(int r, int c) {
return (r>=0 && r<N && c>=0 && c<M);
}
static String src =
"5 7\r\n"
+ "/.....\\\r\n"
+ "../..\\.\r\n"
+ "\\...../\r\n"
+ "/.....\\\r\n"
+ "\\.\\.../\r\n"
+ "3 3";
}
후기
이 문제에서 여태까지 해당 유형에서 내 접근법이 많이 아쉬웠다는 것을 알게되었다. 여태까지 방향을 바꿀때는 switch-case 문으로 위, 아래, 오른쪽, 왼쪽의 경우를 일일이 따졌는데 문제에 따라서 규칙을 발견할 수 있다는 것을 알게되었다. 또한 방향을 dir[] 배열에 정답 출력용 문자를 저장하는 것도 신박했고, 한칸씩 이동하는 것을 항상 ++ 이나 -- 로 풀어서 코드가 길어졌는데, dr[], dc[]로 하는 것도 배울점 이었다.
'Algorithm' 카테고리의 다른 글
[백준] S2 5464 주차장 (java) (0) | 2021.07.13 |
---|---|
[백준] S2 16924 십자가 찾기 (java) (0) | 2021.07.12 |
[백준] S2 1713 후보 추천하기 (java) (0) | 2021.07.12 |
[백준] G4 1261 알고스팟 (java) (0) | 2021.07.10 |
[백준] G5 17396 백도어 (java) (0) | 2021.07.09 |
- Total
- Today
- Yesterday
- G5
- 백트래킹
- SWEA
- 리액트
- 다익스트라
- Spring Boot
- 코딩새내기
- 시뮬레이션
- java
- 우선순위큐
- g4
- S2
- react native
- 현꾸라지
- laugh4mile
- S3
- 자바
- 알고리즘
- 백준
- react
- 리액트 네이티브
- PriorityQueue
- 문자열
- Spring
- 구현
- map
- DFS
- BFS
- 그리디
- 객체지향
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |