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

 

16973번: 직사각형 탈출

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

www.acmicpc.net

문제풀이

이번 문제는 BFS문제에 범위를 추가하여 진행하는 문제였습니다.

주어지는 직사각형의 가로길이와 세로길이를 받아서 해당 범위내에 벽이 있는지 체크하면서 진행합니다.

이 문제같은경우 유의해야할 사항은,
직사각형을 돌면서 벽이 있는지 체크하면 모든 BFS 경우마다 NXM 만늠 연산을 수행하므로 시간초과가 날 수 있습니다.
해결방법은, 벽의 위치를 list에 넣어서, 벽의 위치가  x ~ x + H, y ~ y + W 에 있다면 직사각형 안에 벽이 있는것이므로 실패처리합니다.

위의 방식으로 진행하면 해결할 수 있습니다.

 

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
	
	public static int N,M;
	public static int[][] map;
	public static boolean[][] visited;
	public static int H,W,sr,sc,fr,fc;
	public static int result = 0;
	public static ArrayList<Integer[]> arr = new ArrayList<>();
    public static void main(String[] args) throws IOException{
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    	StringTokenizer st = new StringTokenizer(br.readLine());
    	
    	N = Integer.parseInt(st.nextToken());
    	M = Integer.parseInt(st.nextToken());
    	
    	map = new int[N+1][M+1];
    	visited = new boolean[N+1][M+1];
    	for(int i=1;i<=N;i++) {
    		st = new StringTokenizer(br.readLine());
    		for(int j=1;j<=M;j++) {
    			map[i][j] = Integer.parseInt(st.nextToken());
    			if(map[i][j] == 1) {
    				arr.add(new Integer[] {i,j});
    			}
    		}
    	}
    	
    	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();
    	
    	if(result!= 0) {
    		System.out.println(result);
    	}else {
    		System.out.println("-1");
    	}
    	
    }
    
    public static void bfs() {
    	int[] dx = {-1,1,0,0};
    	int[] dy = {0,0,-1,1};
    	Queue<Node> q = new LinkedList<>();
    	q.offer(new Node(sr, sc, 0));
    	visited[sr][sc] = true;
    	
    	while(!q.isEmpty()) {
    		Node temp = q.poll();
    		int x = temp.x;
    		int y = temp.y;
    		int cnt = temp.cnt;
    		
    		if(x == fr && y == fc) {
    			result = cnt;
    			return;
    		}
    		
    		for(int dir=0;dir<4;dir++) {
    			int nx = x + dx[dir];
    			int ny = y + dy[dir];
    			
    			if( nx < 1 || nx + H - 1> N || ny < 1 || ny + W - 1 > M) continue;
    			if(Check(nx, ny) == false) continue;
    			if(visited[nx][ny] == true) continue;
    			if( map[nx][ny] == 1 )continue;
    			q.offer(new Node(nx, ny, cnt + 1));
    			visited[nx][ny] = true;
    		}
    	}
    }
    
    public static boolean Check(int x, int y) {
    	for(int i=0;i<arr.size();i++) {
    		int wallx = arr.get(i)[0];
    		int wally = arr.get(i)[1];
    		
    		if( x <= wallx && wallx <= x + H - 1 && y <= wally && wally <= y + W - 1) {
    			return false;
    		}
    	}
    	return true;
    }
   
}

class Node{
	int x;
	int y;
	int cnt;
	public Node(int x, int y, int cnt) {
		this.x=x;
		this.y=y;
		this.cnt = cnt;
	}
}

 

+ Recent posts