담배팔이소년

[BOJ] 17836 공주님을 구해라! 본문

Algorithm

[BOJ] 17836 공주님을 구해라!

bkkmw 2023. 7. 3. 18:02

https://www.acmicpc.net/problem/17836

 

17836번: 공주님을 구해라!

용사는 마왕이 숨겨놓은 공주님을 구하기 위해 (N, M) 크기의 성 입구 (1,1)으로 들어왔다. 마왕은 용사가 공주를 찾지 못하도록 성의 여러 군데 마법 벽을 세워놓았다. 용사는 현재의 가지고 있는

www.acmicpc.net

 

문제 풀이

 

package boj;

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

public class MainB_17836 {

	public static int[][] dir_yx = new int[][] {{-1,0}, {0,+1}, {+1,0}, {0,-1}};
	
	public static void main(String[] args) throws Exception {
		System.setIn(new FileInputStream("input/boj/input_17836.txt"));
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		int T = Integer.parseInt(st.nextToken());
		
		int[][] map = new int[N][M];
		int[] gram_pos = new int[2];
		
		for(int i=0; i<N; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for(int j=0; j<M; j++) {
				int temp = Integer.parseInt(st.nextToken());
				map[i][j] = temp;
				if(temp == 2) gram_pos = new int[] {i, j}; 
			}
		}
		
		int ans = solve(N, M, T, map, gram_pos);
		System.out.println(ans == -1 ? "Fail" : ans);
	}
	
	public static int solve(int N, int M, int T, int[][] map, int[] gram_pos) {
		int ret = -1;
		boolean[][] visited = new boolean[N][M];
		Queue<int[]> q = new LinkedList<>();
		int[] arrival_t = new int[2];
		int l1_dist = (N-1-gram_pos[0]) + (M-1-gram_pos[1]);
		
		visited[0][0] = true;
		q.add(new int[] {0, 0, 0});
		
		while(!q.isEmpty()) {
			int cur[] = q.poll();
			
			if(cur[2]+1 > T || check_time(arrival_t, cur[2]+1, l1_dist)) break;
			
			for(int d=0; d<4; d++) {
				int ny = cur[0] + dir_yx[d][0];
				int nx = cur[1] + dir_yx[d][1];
				
				if(ny<0 || ny>N-1 || nx<0 || nx>M-1) continue;
				if(visited[ny][nx]) continue;
				if(map[ny][nx] == 1) continue;
				
				visited[ny][nx] = true;

				if(map[ny][nx] == 2) {
					arrival_t[0] = (cur[2] + 1 + l1_dist) > T? 0 : cur[2]+1+l1_dist;
					continue;
				}
				
				if(ny == N-1 && nx == M-1) {
					arrival_t[1] = cur[2] + 1;
					continue;
				}
				
				q.add(new int[] {ny, nx, cur[2] + 1});
			}
		}
		
		return calc_ret(arrival_t);
	}
	
	public static boolean check_time(int[] arrivals, int current, int l1_dist) {
		boolean acquired = arrivals[0] > 0;
		boolean arrived = arrivals[1] > 0;
		
//		if((!acquired) && (!arrived)) return false;
		if(acquired && arrived) return true;
		
		if(acquired && (current >= arrivals[0])) return true;
		if(arrived && (current >= arrivals[1] - l1_dist)) return true;
		
		return false;
	}
	
	public static int calc_ret(int[] arrivals) {
		if(arrivals[0] < 1 && arrivals[1] < 1) return -1;
		if(arrivals[0] < 1) return arrivals[1];
		if(arrivals[1] < 1) return arrivals[0];
		return (arrivals[0] > arrivals[1] ? arrivals[1] : arrivals[0]);
	}
}

 

'Algorithm' 카테고리의 다른 글

[BOJ] 06198 옥상 정원 꾸미기  (0) 2023.07.19
[BOJ] 13459 구슬 탈출  (1) 2023.07.12
[BOJ] 02636 치즈  (0) 2023.06.30
[BOJ] 01194 달이 차오른다, 가자.  (0) 2023.06.01
[BOJ] 17825 주사위 윷놀이  (0) 2023.04.27
Comments