Algorithm/백준

[백준] 16973 직사각형 탈출

SSONGMI 2021. 4. 19. 23:01
반응형

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

 

16973번: 직사각형 탈출

크기가 N×M인 격자판에 크기가 H×W인 직사각형이 놓여 있다. 격자판은 크기가 1×1인 칸으로 나누어져 있다. 격자판의 가장 왼쪽 위 칸은 (1, 1), 가장 오른쪽 아래 칸은 (N, M)이다. 직사각형의 가장

www.acmicpc.net

: 직사각형이 주어진 도착지까지 이동하기까지 걸리는 최소 이동 횟수를 구해야 한다.

: 직사각형을 클래스로 만들어 왼쪽 위, 아래, 오른쪽 위, 아래의 좌표를 저장할 수 있도록 한다.

: 델타 탐색으로 이동하면서 각 좌표안에 벽이 있는지 판단할 수 있도록 한다.

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

public class 직사각형탈출 {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringBuilder sb = new StringBuilder();
	static StringTokenizer st;
	static int N, M, sr, sc, h, w, fr,fc;
	static int[][] map;
	static boolean[][] v;
	static int[] dr = {-1, 1, 0, 0};
	static int[] dc = {0, 0, -1, 1};
	static class Point{
		int sr, sc, er,ec, cnt;

		public Point(int sr, int sc, int er, int ec) {
			super();
			this.sr = sr;
			this.sc = sc;
			this.er = er;
			this.ec = ec;
		}

		public Point(int sr, int sc, int er, int ec, int cnt) {
			super();
			this.sr = sr;
			this.sc = sc;
			this.er = er;
			this.ec = ec;
			this.cnt = cnt;
		}
		
	}
	public static void main(String[] args) throws IOException {
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		map = new int[N+1][M+1];
		v =new boolean[N+1][M+1];
		for(int i = 1; i <N+1; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j = 1; j < M+1; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		st = new StringTokenizer(br.readLine());
		h = Integer.parseInt(st.nextToken());
		w = Integer.parseInt(st.nextToken());
		sr = Integer.parseInt(st.nextToken());
		sc = Integer.parseInt(st.nextToken());
		fr = Integer.parseInt(st.nextToken());
		fc = Integer.parseInt(st.nextToken());
		bfs(sr, sc, sr+h-1, sc+w-1);
		if(min == Integer.MAX_VALUE)System.out.println("-1");
		else System.out.println(min);
		
	}
	static int min = Integer.MAX_VALUE;
	
	private static void bfs(int sr, int sc, int er, int ec) {
		Queue<Point> q = new LinkedList<>();
		q.offer(new Point(sr, sc, er, ec, 0));
		v[sr][sc] = true;
		
		while(!q.isEmpty()) {
			Point cur = q.poll();
			if(cur.sr == fr && cur.sc == fc) {
				min = min > cur.cnt ? cur.cnt : min;
				return;
			}
			for(int i = 0; i < 4; i++) {
				int nsr = cur.sr + dr[i];
				int nsc = cur.sc + dc[i];
				int ner = cur.er + dr[i];
				int nec = cur.ec + dc[i];
				
				// 범위 밖으로 나갈때
				if(nsr < 1 || nsr > N || nsc < 1 || nsc > M || ner < 1 || ner > N || nec < 1 || nec > M || v[nsr][nsc])continue;
				
				// 이동하려는 자리 중 하나라도 1일 때
				if(check(nsr, nsc, ner, nec)) continue;
				v[nsr][nsc] = true;
				q.offer(new Point(nsr, nsc, ner, nec, cur.cnt+1));
			}
		}
	}

	private static boolean check(int nsr, int nsc, int ner, int nec) {
		for(int i = nsr; i <= ner ; i++) {
			for(int j = nsc; j <= nec; j++) {
				if(map[i][j] == 1) return true;
			}
		}
		return false;
	}

}
반응형