어흥

[백준 16973] 직사각형 탈출 (C++) 본문

알고리즘/백준

[백준 16973] 직사각형 탈출 (C++)

라이언납시오 2020. 4. 17. 11:33
728x90
반응형

문제 링크: https://www.acmicpc.net/problem/16973

 

16973번: 직사각형 탈출

크기가 N×M인 격자판에 크기가 H×W인 직사각형이 놓여 있다. 격자판은 크기가 1×1인 칸으로 나누어져 있다. 격자판의 가장 왼쪽 위 칸은 (1, 1), 가장 오른쪽 아래 칸은 (N, M)이다. 직사각형의 가장 왼쪽 위칸은 (Sr, Sc)에 있을 때, 이 직사각형의 가장 왼쪽 위칸을 (Fr, Fc)로 이동시키기 위한 최소 이동 횟수를 구해보자. 격자판의 각 칸에는 빈 칸 또는 벽이 있다. 직사각형은 벽이 있는 칸에 있을 수 없다. 또한, 직사각형은 격자

www.acmicpc.net

1. 주의할 점

- 이동할 때, 범위를 벗어나지 않도록 한다

- 이동할 때, 다음 위치가 1이면 가지않는다

- 이미 가본 위치라면 가지 않는다

- 이동이 가능한지 판별 할 때, 새롭게 이동되는 칸만 확인한다. 전체 직사각형 확인 -> TLE

 

2. 구현

- BFS를 통하여 4방향 탐색을 통하여 다음 칸으로 이동할 수 있는지 확인한다

- 이동할 수 있다면, Test() 함수를 통해 새롭게 차지하는 칸에 1이 없는지 확인한다

- 목표지점에 도달했으면 While문을 종료한다

 

#define MAX 987654321
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int arr[1000][1000];
bool check[1000][1000] = { false, };
int dx[4] = { 0,1,0,-1 };
int dy[4] = { -1,0,1,0 };

struct info {
	int x, y, val;
};
info tmp;
int row, col, r, c, sx, sy, tx, ty, result = MAX;

bool test(int y, int x, int dir) {
	if (dir == 0) {		//위로 이동
		for (int i = x; i < x + c; i++) {
			if (arr[y][i] == 1)
				return false;			
		}
	}
	else if (dir == 1) {		//오른쪽으로 이동
		int nx = x + c - 1;
		if (nx >= col) return false;
		for (int i = y; i < y + r; i++)
			if (arr[i][nx] == 1)
				return false;
	}
	else if (dir == 2) {		//아래로 이동
		int ny = y + r - 1;
		if (ny >= row) return false;
		for (int i = x; i < x + c; i++) {
			if (arr[ny][i] == 1)
				return false;
		}
	}
	else if (dir == 3) {		//왼쪽으로 이동
		for (int i = y; i < y + r; i++)
			if (arr[i][x] == 1)
				return false;
	}
	return true;
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
	cin >> row >> col;
	for (int i = 0; i < row; i++)
		for (int j = 0; j < col; j++) 
			cin >> arr[i][j];		
	cin >> r >> c >> sy >> sx >> ty >> tx;
	sy--; sx--; ty--; tx--;
	queue<info> q;
	tmp.x = sx;
	tmp.y = sy;
	tmp.val = 0;
	q.push(tmp);
	while (!q.empty()) {
		int cx = q.front().x;
		int cy = q.front().y;
		int cv = q.front().val;
		q.pop();
		if (cx == tx && cy == ty) {
			result = cv;
			break;
		}
		for (int i = 0; i < 4; i++) {
			int nx = cx + dx[i];
			int ny = cy + dy[i];
			if (nx >= 0 && ny >= 0 && nx<col && ny<row && !check[ny][nx] && arr[ny][nx]==0) {
				check[ny][nx] = true;
				if (test(ny, nx,i)) {		//이동 가능한 경우
					tmp.x = nx;
					tmp.y = ny;
					tmp.val = cv + 1;
					q.push(tmp);
				}
			}
		}
	}
	if (result == MAX) result = -1;
	cout << result;
	system("pause");
	return 0;
}
728x90
반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 2665] 미로만들기 (C++)  (0) 2020.04.18
[백준 1799] 비숍 (C++)  (0) 2020.04.18
[백준 7682] 틱택토 (C++)  (2) 2020.04.16
[백준 1944] 복제 로봇 (C++)  (0) 2020.04.15
[백준 1504] 특정한 최단 경로 (C++)  (0) 2020.04.14
Comments