https://www.acmicpc.net/problem/3190
1. Queue : 뱀의 움직임 관리 Queue<Snake> moveInfo
2. Deque : 뱀 자체 관리 Deque<Dot> snake
3. int[][] : 사과의 위치 관리 map
4. class Dot : 뱀이나 사과의 위치 값 관리
5. class Snake : 뱀이 움직일 위치 정보 기록
6. move() : 뱀이 움직임에 대한 메서드
뱀이 사과를 먹으면 커지고 안 먹으면 안 커지거나 코너에서의 방향 전환에 대해 생각하기가 조금 어려웠다.
뱀이 사과를 먹으면 커지는 것에 대해서는 앞으로 한 칸 전진.
뱀이 사과를 못 먹은 것에 대해서는 앞으로 한 칸 전진 후, 제일 마지막 부분 제거(deque에서 pollLast)
코너와 같은 곳에서의 방향 전환은 뱀(deque snake)에서 저장되어 있는 값이기에 따로 변경해줄 필요는 없다.
deque를 사용하면 머리와 꼬리만 관리해줄 수 있기 때문에 비교적 복잡하지 않은 코딩이 가능하다고 생각한다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int N;
static Deque<Dot> snake;
static int[][] map;
public static void main(String[] args) throws Exception {
// Input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
int K = Integer.parseInt(st.nextToken());
map = new int[N + 1][N + 1];
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int row = Integer.parseInt(st.nextToken());
int col = Integer.parseInt(st.nextToken());
map[row][col] = 1;// 사과있음.
}
st = new StringTokenizer(br.readLine());
K = Integer.parseInt(st.nextToken());
Queue<Snake> moveInfo = new LinkedList<>();
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int sec = Integer.parseInt(st.nextToken());
String dir = st.nextToken();
moveInfo.add(new Snake(sec, dir));
}
int sec = 0;
int dir = 0;
snake = new LinkedList<>();
// 뱀은 1,1에서 출발함! 첫 방향은 오른쪽!
snake.add(new Dot(1, 1));
while (true) {
sec++;
if (!move(dir)) {
break;
}
if (!moveInfo.isEmpty() && moveInfo.peek().sec == sec) {
Snake cur = moveInfo.poll();
String curDir = cur.dir;
if ("D".equals(curDir))
dir += 5;
else
dir += 3;
}
dir %= 4;
}
System.out.println(sec + 1);
}
public static boolean move(int dir) {
int[][] dirs = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };// 시계방향
int nextR = snake.peekFirst().row + dirs[dir][0];
int nextC = snake.peekFirst().col + dirs[dir][1];
for (Dot cur : snake) {
if (nextR == cur.row && nextC == cur.col)
return false;
}
if (nextR <= 0 || nextC <= 0 || nextR > N || nextC > N)
return false;
Dot head = new Dot(nextR, nextC);
if (map[nextR][nextC] != 1)
snake.pollLast();
else {
map[nextR][nextC] = 0;
}
snake.addFirst(head);
return true;
}
}
class Dot {
int row;
int col;
Dot(int row, int col) {
this.row = row;
this.col = col;
}
}
class Snake {
int sec;
String dir;
Snake(int sec, String dir) {
this.sec = sec;
this.dir = dir;
}
}
반응형
'알고리즘 문제 풀이 > BOJ' 카테고리의 다른 글
[backjoon]16234 인구 이동 java (0) | 2021.09.26 |
---|---|
[backjoon]12100 2048(easy) java (0) | 2021.09.15 |
[backjoon]15684 사다리 조작 java (0) | 2021.09.01 |
[backjoon]14720 우유 도시 java (0) | 2021.05.08 |
[backjoon]20056 마법사 상어와 파이어볼 java (0) | 2021.04.24 |