[백준] 3190번 뱀

반응형
반응형

문제

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다.

게임은 NxN 정사각 보드위에서 진행되고, 몇몇 칸에는 사과가 놓여져 있다. 보드의 상하좌우 끝에 벽이 있다. 게임이 시작할때 뱀은 맨위 맨좌측에 위치하고 뱀의 길이는 1 이다. 뱀은 처음에 오른쪽을 향한다.

뱀은 매 초마다 이동을 하는데 다음과 같은 규칙을 따른다.

  • 먼저 뱀은 몸길이를 늘려 머리를 다음칸에 위치시킨다.
  • 만약 이동한 칸에 사과가 있다면, 그 칸에 있던 사과가 없어지고 꼬리는 움직이지 않는다.
  • 만약 이동한 칸에 사과가 없다면, 몸길이를 줄여서 꼬리가 위치한 칸을 비워준다. 즉, 몸길이는 변하지 않는다.

사과의 위치와 뱀의 이동경로가 주어질 때 이 게임이 몇 초에 끝나는지 계산하라.

 

이 문제에서 중요한것은 바로

90도 회전이다. 

즉, 동서 남북을 그리고

북쪽을 기준으로 왼쪽 90도는 서

오른쪽 90도는 동이 된다.

이런식으로 하는게 중요하다.

또한 백터좌표를 어떤식으로 작성을 해야하는지도 중요하다.

왜냐하면 순서가 조금이라도 틀리면 답이 다르게 나오기 때문이다.

이 문제 같은 경우는

    //  동 북 서 남
    static int[] dy = {0, -1, 0, 1};
    static int[] dx = {1, 0, -1, 0};

동 북 서 남으로 했다. 사실 x좌표와 y좌표를 순서를 바꿔줘야한다. 정확한 이유는 모르지만 뭔가의 불일치 때문에 나타나는 현상인듯 싶다.

아무튼 이렇게 좌표를 지정하고

회전을 해야하는데 

나는 메서드를 따로 만들었다.

private static int turn(int d, char c) {
        if (c == 'L') {
            return (d + 1) % 4;
        }
        return (d + 3) % 4;
    }

파이썬에서는 +3이아닌-1도 가능하다 그러는데

자바는 불가능하다. 이유는 직접 해보면 될것 같다.

package _12.Implentation;

import java.util.*;

class Node01 {
    int time;
    char direction;

    public Node01(int time, char direction) {
        this.time = time;
        this.direction = direction;
    }
}

public class Snake2 {
    static int n, k, l;
    static int[][] maps;
    //  동 북 서 남
    static int[] dx = {0, -1, 0, 1};
    static int[] dy = {1, 0, -1, 0};
    static List<Node01> info = new ArrayList<>();

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        k = sc.nextInt();

        maps = new int[n + 10][n + 10];
        for (int i = 0; i < k; i++) {
            int a = sc.nextInt();
            int b = sc.nextInt();
            maps[a][b] = 1;
        }

        l = sc.nextInt();

        for (int i = 0; i < l; i++) {
            int time = sc.nextInt();
            char direction = sc.next().charAt(0);
            info.add(new Node01(time, direction));
        }

        int result = solution();
        System.out.println(result);
    }

    private static int turn(int d, char c) {
        if (c == 'L') {
            return (d + 1) % 4;
        }
        return (d + 3) % 4;
    }

    private static int solution() {
        int x = 1, y = 1;
        int direction = 0;
        int index = 0;
        int time = 0;
        maps[x][y] = 2;

        Queue<int[]> q = new LinkedList<>();
        q.offer(new int[]{x, y});
        while (!q.isEmpty()) {
            int nx = x + dx[direction];
            int ny = y + dy[direction];
            if (1 > nx || nx > n || 1 > ny || ny > n || maps[nx][ny] == 2) {
                time+=1;
                break;
            }


            if (maps[nx][ny] == 0) {
                int[] prev = q.poll();
                maps[prev[0]][prev[1]] = 0;
            }

            maps[nx][ny] = 2;
            q.offer(new int[]{nx, ny});
            x = nx;
            y = ny;
            time++;
            if (index < l && info.get(index).time == time) {
                direction = turn(direction, info.get(index).direction);
                index++;
            }
        }
        return time;
    }
}

 

 

c++ ( 내코드 아님)

'
int N, K, L;
int board[105][105];
queue<pii> Q;
int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0);
	sf1(N);
	sf1(K);
	while (K--) {
		int a, b;
		sf2(a, b); a--; b--;
		board[a][b] = 1;
	}
	int ans = 0;
	sf1(L);
	int curX = 0;
	int curY = 0;
	Q.push({ 0,0 });
	board[0][0] = 2;
	int dir = 2; // 0  : down 1 : up 2 : right 3 : left, (0,0)이 좌상단 
	int time = 0;
	while (L--) {
		int x;
		char c;
		sf2(x, c);
		while (time < x) {
			curX = curX + dx[dir];
			curY = curY + dy[dir];
			if (OOB(curX, curY, N, N) || board[curX][curY] == 2) {
				pf1(time+1);
				return 0;
			}
			Q.push({ curX,curY });
			if (board[curX][curY] == 0) {
				board[curX][curY] = 2;
				pii del = Q.front();
				Q.pop();
				board[del.X][del.Y] = 0;
			}
			else // 사과가 있었다면
				board[curX][curY] = 2;			
			time++;
		}
		int Ltable[4] = { 2,3,1,0 };
		int Rtable[4] = { 3,2,0,1 };
		if (c == 'L') dir = Ltable[dir];
		else dir = Rtable[dir];
		
	}
	while (true) {
		curX = curX + dx[dir];
		curY = curY + dy[dir];
		if (OOB(curX, curY, N, N) || board[curX][curY] == 2) {
			pf1(time+1);
			return 0;
		}
		if (board[curX][curY] == 0) {
			board[curX][curY] = 2;
			Q.push({ curX,curY });
			pii del = Q.front();
			Q.pop();
			board[del.X][del.Y] = 0;
		}
		else // 사과가 있었다면
			board[curX][curY] = 2;
		time++;
	}
	return 0;

}
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준] 1149번 RPG 거리  (0) 2020.09.30
[백준] 15686번 치킨 배달  (0) 2020.09.07
[백준] 1931번 회의실 배정  (0) 2020.08.24
[백준] 1946번 신입 사원  (0) 2020.08.24
[백준] 1783번 병든 나이트  (0) 2020.08.22

댓글

Designed by JB FACTORY