백준의 직사각형 탈출(16973) 문제이다.
[ 문제 바로가기 ]
[ 문제 풀이 ]
1) 일반적인 BFS 완전탐색법을 이용하면 쉽게 해결할 수 있는 문제이다. 단지, 일반적으로 하나의 좌표를 움직이는 것이 아닌
크기가 존재하는 사각형을 한번에 움직여 줘야 한다는 부분만 잘 계산해주면 된다.
문제에서, 주어진 사각형의 가장 왼쪽 위에 존재하는 칸이, 도착점에 도달하기 위해서 최소 몇번을 움직여야 하는지
구해야 하는 문제이다.
움직여 줄 때, 움직여주는 방향에 맞게 사각형의 가로 , 세로길이를 적절하게 계산해주고 판단해주면 된다.
[ 소스코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | #include<iostream> #include<queue> #define endl "\n" #define MAX 1000 using namespace std; int N, M, H, W, Sx, Sy, Ex, Ey; int MAP[MAX][MAX]; bool Visit[MAX][MAX]; int dx[] = { 0, 0, 1, -1 }; int dy[] = { 1, -1, 0, 0 }; void Input() { cin >> N >> M; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cin >> MAP[i][j]; } } cin >> H >> W >> Sx >> Sy >> Ex >> Ey; Sx--; Sy--; Ex--; Ey--; } bool Can_Move(int x, int y, int dir) { if (dir == 0) { int ny = y + W - 1; if (ny >= M) return false; for (int i = x; i < x + H; i++) { if (MAP[i][ny] == 1) return false; } } else if (dir == 1) { for (int i = x; i < x + H; i++) { if (MAP[i][y] == 1) return false; } } else if (dir == 2) { int nx = x + H - 1; if (nx >= N) return false; for (int i = y; i < y + W; i++) { if (MAP[nx][i] == 1) return false; } } else if (dir == 3) { for (int i = y; i < y + W; i++) { if (MAP[x][i] == 1) return false; } } return true; } void BFS(int a, int b) { queue<pair<pair<int, int>, int>> Q; Q.push(make_pair(make_pair(a, b), 0)); Visit[a][b] = true; while (Q.empty() == 0) { int x = Q.front().first.first; int y = Q.front().first.second; int Cnt = Q.front().second; Q.pop(); if (x == Ex && y == Ey) { cout << Cnt << endl; return; } for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && ny >= 0 && nx < N && ny < M) { if (Visit[nx][ny] == false) { if (Can_Move(nx, ny, i) == true) { Visit[nx][ny] = true; Q.push(make_pair(make_pair(nx, ny), Cnt + 1)); } } } } } cout << -1 << endl; } void Solution() { BFS(Sx, Sy); } void Solve() { Input(); Solution(); } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글
[ 백준 14391 ] 종이 조각 (C++) (2) | 2019.08.01 |
---|---|
[ 백준 16968 ] 차량 번호판1 (C++) (2) | 2019.08.01 |
[ 백준 16937 ] 두 스티커 (C++) (0) | 2019.08.01 |
[ 백준 16960 ] 스위치와 램프 (C++) (0) | 2019.07.12 |
[ 백준 16958 ] 텔레포트 (C++) (2) | 2019.07.12 |