백준 3190: 뱀

문제보기
Alt text

풀이

  • 시뮬레이션
  • while문 안에 snake 리스트에서 뱀의 위치를 하나씩 꺼내서 볼 때, 뱀의 머리부터 봐야하기 때문에 리스트의 마지막인덱스를 꺼내서 봐야함을 주의.
  • 사과가 있는 칸이면 꼬리가 움직이지 않기 때문에 snake 리스트에 새로 이동한 칸만 넣어준다.
  • 사과가 없는 칸이면 꼬리가 위치한 칸을 비워줘야 하기 때문에 snake 리스트의 첫번째 인덱스를 지우고, 새로 이동한 칸을 넣어준다.

소스코드

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	static class Direction {
		int X;
		String C;

		Direction(int X, String C) {
			this.X = X;
			this.C = C;
		}
	}

	static class Node {
		int r, c;

		Node(int r, int c) {
			this.r = r;
			this.c = c;
		}
	}
	static int[] dr = { -1, 1, 0, 0 };
	static int[] dc = { 0, 0, -1, 1 };

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt(); // 보드 크기
		int[][] board = new int[N + 1][N + 1];
		int K = sc.nextInt(); // 사과 개수
		for (int i = 0; i < K; i++) {
			int r = sc.nextInt();
			int c = sc.nextInt();
			board[r][c] = 1; // 사과의 위치를 보드에 1로 놓기
		}
		int L = sc.nextInt(); // 뱀의 방향 변환 횟수
		ArrayList<Direction> list = new ArrayList<>(); // 뱀의 방향 변환을 담을 리스트
		for (int i = 0; i < L; i++) {
			int X = sc.nextInt(); // 방향 회전할 시간(X초가 끝난 뒤에 회전)
			String C = sc.next(); // 회전할 방향(D가 오른쪽, L이 왼쪽)

			list.add(new Direction(X, C));
		}

		int time = 0;
		ArrayList<Node> snake = new ArrayList<>(); // 뱀의 위치를 넣을 리스트
		snake.add(new Node(1, 1));
		int dir = 3; // 뱀이 움직이는 방향(상:0, 하:1, 좌:2, 우:3)
		
		loop: while (true) {
			time++;
			int size = snake.size();
			Node node = snake.get(size-1);
			int nr = node.r + dr[dir];
			int nc = node.c + dc[dir];

			// 벽 또는 자기자신의 몸과 부딪히면 끝
			if (nr <= 0 || nc <= 0 || nr > N || nc > N) {
				break;
			}
			for (int i = 0; i < snake.size(); i++) {
				if (snake.get(i).r == nr && snake.get(i).c == nc)
					break loop;
			}

			//뱀 이동
			if (board[nr][nc] == 1) {
				board[nr][nc] = 0;
				snake.add(new Node(nr, nc));
			} else {
				snake.remove(0);
				snake.add(new Node(nr, nc));
			}
			
			//뱀의 방향 변환 할 거 확인하기
			if(list.size()>0) {
				if(list.get(0).X==time) {
					//내가 보고 있는 방향에서 오른쪽으로 회전
					if(list.get(0).C.equals("D")) {
						if(dir==0)
							dir=3;
						else if(dir==1)
							dir=2;
						else if(dir==2)
							dir=0;
						else if(dir==3)
							dir=1;
					}
					//내가 보고 있는 방향에서 왼쪽으로 회전
					else {
						if(dir==0)
							dir=2;
						else if(dir==1)
							dir=3;
						else if(dir==2)
							dir=1;
						else if(dir==3)
							dir=0;
					}
					
					list.remove(0);
				}
			}
		}
		System.out.println(time);
	}
}