SSONG Cloud

[백준] 1600 말이 되고픈 원숭이 본문

Algorithm/백준

[백준] 1600 말이 되고픈 원숭이

SSONGMI 2021. 3. 24. 21:22
반응형

문제 출처: www.acmicpc.net/problem/1600

 

1600번: 말이 되고픈 원숭이

첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있

www.acmicpc.net

: 원숭이에게 말처럼 움직일 수 있는 횟수가 주어지고 말처럼 이동하거나 인접한 칸으로 이동하여 가장 왼쪽 상단에서 가장 우측 하단으로 이동할 때 소요되는 원숭이의 최소 동작수를 구해야 한다.

: 원숭이에게 주어진 횟수가 달라질 때마다 그리고, 원숭이가 말처럼 행동하거나 행동하지 않을 때마다 다른 갈래로 움직여야 하기 때문에 이를 저장할 수 있도록 visited 배열을 3차원으로 만든다.

: 말처럼 행동할 때마다 말처럼 행동 가능한 횟수를 줄이고 그에 해당하는 visited배열에 표시할 수 있도록 한다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringBuilder sb = new StringBuilder();
	static StringTokenizer st;
	static class Status{
		int x, y, len, cnt; // x좌표, y좌표, 동작 횟수, 말처럼 움직일 수 있는 횟수

		public Status(int x, int y, int len, int cnt) {
			super();
			this.x = x;
			this.y = y;
			this.len = len;
			this.cnt = cnt;
		}

		@Override
		public String toString() {
			return "Status [x=" + x + ", y=" + y + ", len=" + len + ", cnt=" + cnt + "]";
		}
		
	}
	static int[] dr = {-1, 1, 0, 0};
	static int[] dc = {0, 0, -1, 1};
	static int[] horseR = {-2, -1, 1, 2, 2, 1, -1, -2};
	static int[] horseC = {1, 2, 2, 1, -1, -2, -2, -1};
	public static void main(String[] args) throws NumberFormatException, IOException {
		int K = Integer.parseInt(br.readLine()); // K번 말처럼 움직일 수 있음
		st = new StringTokenizer(br.readLine());
		int M = Integer.parseInt(st.nextToken());
		int N = Integer.parseInt(st.nextToken());
		
		int[][] map = new int[N][M];
		for(int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 0; j < M; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		int ans = 0;
		boolean[][][] v = new boolean[N][M][K+1];
		Queue<Status> q = new LinkedList<>();
		q.add(new Status(0,0,0,K));
		
		while(!q.isEmpty()) {
			Status cur = q.poll();
			if(cur.x == N-1 && cur.y == M-1) {
				ans = cur.len;
				break;
			}
			// 원숭이처럼 움직이는 경우
			for(int d = 0; d < 4; d++) {
				int nr = cur.x + dr[d];
				int nc = cur.y + dc[d];
				if(nr < 0 || nr >= N || nc < 0 || nc >= M || map[nr][nc] == 1 || v[nr][nc][cur.cnt]) continue;
				v[nr][nc][cur.cnt] = true;
				q.add(new Status(nr, nc, cur.len+1, cur.cnt));
			}
			// 말처럼 움직일 수 있는 경우
			if(cur.cnt > 0) {
				for(int d = 0; d < 8; d++) {
					int nr = cur.x + horseR[d];
					int nc = cur.y + horseC[d];
					if(nr < 0 || nr >= N || nc < 0 || nc >= M || map[nr][nc] == 1 || v[nr][nc][cur.cnt-1]) continue;		
					v[nr][nc][cur.cnt-1] = true;
					q.add(new Status(nr, nc, cur.len+1, cur.cnt-1));
				}				
			}
		}
		if(N==1 && M == 1)System.out.println(0);
		else if(ans == 0) System.out.println("-1");
		else System.out.println(ans);
		
	}
}
반응형

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

[백준] 2156 포도주 시식  (0) 2021.03.24
[백준] 11727 2xn 타일링 2  (0) 2021.03.24
[백준] 11779 최소비용 구하기2  (0) 2021.03.22
[백준] 1916 최소비용 구하기  (0) 2021.03.22
[백준] 16562 친구비  (0) 2021.03.19
Comments