본문 바로가기
Problem Solving/백준

백준 1600 : 말이 되고픈 원숭이

by Libi 2021. 8. 22.
반응형

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

 

1600번: 말이 되고픈 원숭이

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

www.acmicpc.net

[ 문제풀이 ]

일반적인 bfs + dp 문제에서 말로 움직일 수 있는 방법만 추가된 문제이다.

3차원 배열을 하나 선언해서 말의 방향으로 움직인 횟수에 따라 방문 표시를 해주면 된다.

가로길이가 W이고 세로길이가 H인 것만 주의하자.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
	
	static class Node {
		int y, x, k, move;
		
		public Node(int y, int x, int k, int move) {
			this.y = y;
			this.x = x;
			this.k = k;
			this.move = move;
		}
	}
	
	static int K, W, H;
	static int[][] map;
	static int[][][] visit;
	
	static int[][] dir = {{-1,0},{1,0},{0,1},{0,-1}};
	static int[][] horse = {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,-2},{2,-1},{2,1},{1,2}};
	
	public static void main(String[] args) {
		try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
			K = Integer.parseInt(br.readLine());
			StringTokenizer st = new StringTokenizer(br.readLine());
			W = Integer.parseInt(st.nextToken());
			H = Integer.parseInt(st.nextToken());
			map = new int[H][W];
			visit = new int[K + 1][H][W];
			for (int i = 0; i < H; ++i) {
				st = new StringTokenizer(br.readLine());
				for (int j = 0; j < W; ++j) {
					map[i][j] = Integer.parseInt(st.nextToken());
					for (int k = 0; k <= K; ++k) {
						visit[k][i][j] = (int)1e9;
					}
				}
			}
			bw.write(bfs() + "\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static int bfs() {
		Queue<Node> q = new LinkedList<>();
		q.offer(new Node(0, 0, 0, 0));
		visit[0][0][0] = 0;
		while (!q.isEmpty()) {
			Node n = q.poll();
			
			if (n.y == H - 1 && n.x == W - 1) {
				return n.move;
			}
			
			//일반적인 4방향 탐색
			for (int d = 0; d < 4; ++d) {
				int ny = n.y + dir[d][0];
				int nx = n.x + dir[d][1];
				
				if (ny < 0 || nx < 0 || ny >= H || nx >= W) continue;
				if (map[ny][nx] == 1) continue;
				if (visit[n.k][ny][nx] != (int)1e9 && visit[n.k][ny][nx] <= n.move + 1) continue;
				visit[n.k][ny][nx] = n.move + 1;
				q.offer(new Node(ny, nx, n.k, n.move + 1));
			}
			
			if (n.k >= K) continue;
			//말이 갈 수 있는 8방향 탐색
			for (int d = 0; d < 8; ++d) {
				int ny = n.y + horse[d][0];
				int nx = n.x + horse[d][1];

				if (ny < 0 || nx < 0 || ny >= H || nx >= W) continue;
				if (map[ny][nx] == 1) continue;
				if (visit[n.k + 1][ny][nx] != (int)1e9 && visit[n.k + 1][ny][nx] <= n.move + 1) continue;
				visit[n.k + 1][ny][nx] = n.move + 1;
				q.offer(new Node(ny, nx, n.k + 1, n.move + 1));
			}
		}
		return -1;
	}
}

 

 

반응형

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

백준 15678 : 연세워터파크  (0) 2021.08.24
백준 9328 : 열쇠  (0) 2021.08.23
백준 2021 : 최소 환승 경로  (0) 2021.08.21
백준 11003 : 최솟값 찾기  (0) 2021.08.20
백준 1956 : 운동  (0) 2021.08.19

댓글