PS
백준 16973번 직사각형 탈출
남마허
2020. 4. 8. 21:00
https://www.acmicpc.net/problem/16973
16973번: 직사각형 탈출
크기가 N×M인 격자판에 크기가 H×W인 직사각형이 놓여 있다. 격자판은 크기가 1×1인 칸으로 나누어져 있다. 격자판의 가장 왼쪽 위 칸은 (1, 1), 가장 오른쪽 아래 칸은 (N, M)이다. 직사각형의 가장 왼쪽 위칸은 (Sr, Sc)에 있을 때, 이 직사각형의 가장 왼쪽 위칸을 (Fr, Fc)로 이동시키기 위한 최소 이동 횟수를 구해보자. 격자판의 각 칸에는 빈 칸 또는 벽이 있다. 직사각형은 벽이 있는 칸에 있을 수 없다. 또한, 직사각형은 격자
www.acmicpc.net
<접근방법>
사이즈가 있는 직사각형의 bfs입니다.
큐에 넣을때마다 2중 for문으로 확인 작업을 하면 시간초과가 납니다.
bfs를 돌리기 전에 좌측상단의 점을 기준으로 잡고 그 점이 가지못하는 곳에 방문체크를 했습니다.
이렇게 하면 일반 bfs와 똑같아집니다.
<느낀 점>
<코드>
#include <iostream>
#include <algorithm>
#include <queue>
#include <memory.h>
using namespace std;
const int MAX = 1000;
int n, m, h, w, sy, sx, fy, fx;
int map[MAX][MAX];
bool visit[MAX][MAX];
int dy[4] = { 1, -1, 0, 0 };
int dx[4] = { 0, 0, 1, -1 };
struct point {
int y, x, cnt;
};
queue<point> q;
bool check(int y, int x) {
for (int ty = y; ty < y + h; ty++) {
for (int tx = x; tx < x + w; tx++) {
if (ty < 0 || ty >= n || tx < 0 || tx >= m) return false;
if (map[ty][tx] == 1) return false;
}
}
return true;
}
int bfs() {
q.push({sy, sx, 0});
visit[sy][sx] = true;
while (!q.empty()) {
point t = q.front();
q.pop();
if (t.y == fy && t.x == fx) return t.cnt;
for (int i = 0; i < 4; i++) {
int ty = t.y + dy[i];
int tx = t.x + dx[i];
if (ty < 0 || ty + h-1 >= n || tx < 0 || tx + w-1 >= m) continue;
if (visit[ty][tx]) continue;
q.push({ty, tx, t.cnt + 1});
visit[ty][tx] = true;
}
}
return -1;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> map[i][j];
}
}
cin >> h >> w >> sy >> sx >> fy >> fx;
sy--; sx--; fy--; fx--;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 1) {
for (int y = i; y > i - h; y--) {
if (y < 0) break;
for (int x = j; x > j - w; x--) {
if (x < 0) break;
visit[y][x] = true;
}
}
}
}
}
/*puts("");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << visit[i][j] << ' ';
}
puts("");
}*/
cout << bfs() << '\n';
return 0;
}
반응형