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; } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 2573 빙산 - BFS + 구현 JAVA (0) | 2023.06.27 |
---|---|
[백준] 18513 샘터 - BFS JAVA (0) | 2023.06.27 |
[백준] 2636 치즈 - BFS JAVA (0) | 2023.06.25 |
[백준] 5547 일루미네이션 - BFS(너비우선탐색) + 아이디어(Idea) JAVA (0) | 2023.06.24 |
[백준] 13023 ABCDE - DFS, 시간초과 JAVA (0) | 2023.06.24 |