danbibibi
article thumbnail

문제

문제 바로가기> BOJ 1600번: 말이 되고픈 원숭이

 

1600번: 말이 되고픈 원숭이

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

www.acmicpc.net

 

풀이

bfs + 3차원 배열을 이용해서 풀었다.

visitCnt[y][x][k] : 말처럼 이동할 수 있는 기회가 k번 남았을 때, (y, x) 에 도달하는 최소 횟수

 

import java.io.*;
import java.util.*;

public class Main {
	
	static final int dy[] = {-1, 1, 0, 0, -2, -2, -1, -1, 1, 1, 2, 2};
	static final int dx[] = {0, 0, -1, 1, -1, 1, -2, 2, -2, 2, -1, 1};
	
	static int K, Y, X;
	static boolean[][] iswall;
	static int[][][] visitCnt;
	
	private static int solution() {
		ArrayDeque<int[]> q = new ArrayDeque<>(); // y, x, k, cnt
		q.push(new int[] {0, 0, K, 0});
		visitCnt[0][0][K] = 0;
		
		int ans = -1;
		while(!q.isEmpty()) {
			int y = q.peek()[0];
			int x = q.peek()[1];
			int k = q.peek()[2];
			int cnt = q.peek()[3];
			q.poll();
			
			if(y==Y-1 && x==X-1) return cnt;
			
			for(int d=0; d<4; d++) {
				int ny = y+dy[d];
				int nx = x+dx[d];
				
				if(ny<0 || ny>=Y || nx<0 || nx>=X || iswall[ny][nx]) continue;
				if(visitCnt[ny][nx][k]==0 || cnt+1 < visitCnt[ny][nx][k]) {
					q.offer(new int[] {ny, nx, k, cnt+1});
					visitCnt[ny][nx][k] = cnt+1;
				}
			}
			
			for(int d=4; d<dy.length; d++) {
				int ny = y+dy[d];
				int nx = x+dx[d];
				
				if(ny<0 || ny>=Y || nx<0 || nx>=X || iswall[ny][nx] || k==0) continue;					
				if(visitCnt[ny][nx][k-1]==0 || cnt+1 < visitCnt[ny][nx][k-1]) {
					q.offer(new int[] {ny, nx, k-1, cnt+1});
					visitCnt[ny][nx][k-1] = cnt+1;
				}
			}
		}
		return ans;
	}
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = null;
		
		K = Integer.parseInt(br.readLine());
		st = new StringTokenizer(br.readLine());
		X = Integer.parseInt(st.nextToken());
		Y = Integer.parseInt(st.nextToken());
		
		iswall = new boolean[Y][X];
		visitCnt = new int[Y][X][K+1];
		
		for(int i=0; i<Y; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=0; j<X; j++)
				iswall[i][j] = (Integer.parseInt(st.nextToken())==0 ? false:true);
		}
		System.out.println(solution());
	}
}

'문제 풀이 > 백준' 카테고리의 다른 글

BOJ 1194번: 달이 차오른다, 가자.  (0) 2023.03.31
BOJ 17836번: 공주님을 구해라!  (0) 2023.03.30
BOJ 16724번: 피리 부는 사나이  (0) 2023.03.29
BOJ 2193번: 이친수  (0) 2023.03.28
BOJ 17404번: RGB거리 2  (0) 2023.03.23
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로