[C++][Baekjoon][BFS νμ] 2206λ² λ²½ λΆμκ³ μ΄λνκΈ° μμΈ ν΄μ€
[λ¬Έμ ]
2206λ²: λ²½ λΆμκ³ μ΄λνκΈ°
N×Mμ νλ ¬λ‘ ννλλ λ§΅μ΄ μλ€. λ§΅μμ 0μ μ΄λν μ μλ κ³³μ λνλ΄κ³ , 1μ μ΄λν μ μλ λ²½μ΄ μλ κ³³μ λνλΈλ€. λΉμ μ (1, 1)μμ (N, M)μ μμΉκΉμ§ μ΄λνλ € νλλ°, μ΄λ μ΅λ¨ κ²½λ‘
www.acmicpc.net
N×Mμ νλ ¬λ‘ ννλ λ§΅μμ (1, 1)μμ (N, M)κΉμ§ μ΄λν λ 걸리λ μ΅λ¨ κ²½λ‘λ₯Ό ꡬνλ λ¬Έμ .
μ΄ λ, 0μ μ΄λν μ μλ κ³³μ λνλ΄κ³ , 1μ μ΄λν μ μλ λ²½μ΄ μλ κ³³μ λνλ΄λ©° 1νμ ννμ¬ λ²½μ λΆμκ³ μ΄λν μ μλ€.
[νμ΄]
Break μ 무λ₯Ό μ μ₯ν΄λκ³ νλ²λ κΉ¬ μ μλ λ²½μ κΉ¨κ°λ©΄μ νμν΄μΌ ν κ² κ°μλ° κ·Έ ꡬ쑰λ₯Ό λͺ»μ§κ² μ΄μ νμ°Έμ ν€λ§Έλ€.
κ²°κ΅ νμ΄ μ°Έμ‘°...
μ΄ λ¬Έμ μ ν΅μ¬μ νμν κ²½λ‘λ₯Ό queueμ μ μ₯ν λ, λ²½μ λΆμ κ²½λ‘μΈμ§ λ²½μ λΆμμ§ μμ κ²½λ‘μΈμ§λ μ μ₯ν΄μ€μΌ νλ€λ μ μ΄λ€. λν, νμν κ²½λ‘λ₯Ό 방문체ν¬ν λ λ²½μ λΆμ μ μ΄ μμΌλ©΄μ λ°©λ¬Έν μλ μκ³ λ²½μ λΆμμ μ΄ μμΌλ©΄μ λ°©λ¬Έν μλ μκΈ° λλ¬Έμ λ κ°μ§ κ²½μ°μ μλ₯Ό λͺ¨λ μ΄μ΄λκ³ ν κ²½μ°λ§ λ°©λ¬Έ 체ν¬ν΄μ€μΌνλ€λ μ μ΄λ€.
μ΄ λ, λ²½μ λΆμ μ μ΄ μλ€λ©΄ λ²½μ΄ μλ κ²½λ‘λ₯Ό κ³μν΄μ μ΄λνλ©΄ λκ³ , λ²½μ λΆμ μ μ΄ μλ€λ©΄ λ²½κ³Ό λ²½μ΄ μλ κ³³ λͺ¨λ μ΄λκ°λ₯νλ€.
μ¦, κ° μ λ€μ μ’νμ λ²½μ λΆμ νμ, μ΄λ νμ μ 보λ₯Ό κ°κ³ μμ΄μΌ νλ€. μ΄λ νμ μ 보λ μ΅λ¨κ²½λ‘κΈΈμ΄λ₯Ό μ°ΎμμΌνκΈ° λλ¬Έμ μ μ₯ν΄μ€¬λ€. νμν λλ§λ€ +1μ©ν΄μ κ²½λ‘ κΈΈμ΄λ₯Ό μ°Ύλλ€.
class Point {
public:
int x;
int y;
int breakCount;//λ²½μ λΆμ νμ. 0 or 1λ‘ νν
int count;//μ΄λ νμ. λμ€μ μΆλ ₯ν΄μ€μΌ ν¨.
Point(int x, int y, int breakCount, int count) {
this->x = x;
this->y = y;
this->breakCount = breakCount;
this->count = count;
}
};
κ·Έλ¦¬κ³ λ²½μ λ«μ μ μ΄ μλ κ²½λ‘κ° λ°©λ¬Έμ²΄ν¬λ₯Ό νλ©° νμνλ κ²½μ°μ λ²½μ λ«μ μ μλ κ²½λ‘κ° λ°©λ¬Έμ²΄ν¬νλ©° νμνλ κ²½μ°. 2κ°μ§λ‘ λλκΈ° λλ¬Έμ visited λ°°μ΄μ 2κ° λ§λ€μ΄μ€μΌ νλ€. κ·Έ λ°°μ΄μ 3μ°¨μ νλ ¬λ‘ νννλ€. λ²½μ λ«μ μ μμΌλ©΄μ λ°©λ¬Ένλ€λ©΄ visited[x][y][0] = trueλ‘, λ²½μ λ«μ μ μμΌλ©΄μ λ°©λ¬Ένλ€λ©΄ visited[x][y][1] = true λ‘ μ²΄ν¬ν κ±°λ€.
bool visited[MAX_VALUE][MAX_VALUE][2] = { false, };
μ¬κΈ°μ μ§λ¬Έμ΄ μμ κ²μ΄λ€. (λλ κ³μ μ΄ν΄κ° μκ°λ λΆλΆ!!) λ²½μ λ«μ λ, νμ μ΅μ μ΄ λλ κ²½μ°λ₯Ό λ«μ΄μΌ ν ν λ°, μμμ λ«μ κ²½μ°λ³΄λ€ λ€μμ λ«μ κ²½μ°κ° λ μ΅μ μ΄λ©΄ μ΄λ‘νμ§????
κ²°λ‘ μ μκ΄μλ€ !!! λ€μ λμ€λ μ΅μ μ κ²½μ°λ λ²½μ λ«μ μ μλ κ²½λ‘κ° μ¬νμν΄μ€ κ²μ΄κΈ° λλ¬Έμ΄λ€ !!!!!
μλ μμ λ₯Ό 보며 μ΄ν΄ν΄λ³΄μ.
μμ 1λ²μ νμ΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
queueμ μ μ₯λλ μΈμ 3κ°λ Pointμ 보λ₯Ό μλ―Ένλλ° μμλλ‘ Point(xμ’ν, yμ’ν, λ²½μ λΆμ νμ)μ΄λ€.
μ¦, 맨 μ²μμ νμ μ μ₯λλ κ°μ xμ’ν 1, yμ’ν 1, λ²½μ λΆμ νμ 0μ μ μ₯νλ€.
κ·Έλ¦¬κ³ (1, 1)λΆν° μ€λ₯Έμͺ½, μλ, μΌμͺ½, μ μμΌλ‘ μ£Όλ³μ νμνλ€.
(1, 1) μ£Όμ μ’νμΈ (1, 2)μ (2, 1)μ νμνλλ°, μμ§ λ²½μ λΆμ νμκ° 0μ΄λ―λ‘ λ²½μ λ§λ¬μ λ λ²½μ λΆμ μ μλ€.
λ°λΌμ λ²½μ λΆμκ³ λ€μ κ²½λ‘λ‘ μ΄λν κ²μ΄λ€. μ¦, visited[1][2][1] = visited[2][1][1] = trueλ‘ λ°©λ¬Έ 체ν¬ν΄μ£Όκ³ queueμ Point(1, 2, 1)κ³Ό Point(2, 1, 1)μ λ£λλ€.
λ€μ queueμ 맨 μμ μλ Point(1, 2, 1)μ κΊΌλ΄μ νμμ μ§νν 건λ°,
μ΄λ―Έ μμμ λ²½μ λΆμ μ μ΄ μμΌλ―λ‘(3λ²μ§Έ μΈμκ° 1μ΄λ―λ‘) λ€μ κ²½λ‘μμ λ²½μ΄ μλ κ²½λ‘(map[x][y] = 0)λ§ νμμ΄ κ°λ₯νλ€. κ·Έλ¦¬κ³ λ²½μ λΆμ μ μ΄ μμΌλ―λ‘ breakedCountλ₯Ό +1 ν΄μ€ μνμΈ Point(1, 3, 1) λ₯Ό queueμ μ μ₯νκ³ λ²½μ λΆμκ³ λ°©λ¬Ένλ€λ νμλ‘ visited[1][3][1] = trueλ‘ λ°©λ¬Έ μ²΄ν¬ ν΄μ€λ€.
κ·Έ λ€λ‘λ λ²½μ λΆμ μ μλ νμκ° 0μ΄λ―λ‘ λ²½μ΄ μλ κ²½λ‘λ§ νμνλ©° (N, M) μ’νμ λλ¬ν κ²μ΄λ€.
λ€λ₯Έ μμ λ μ΄ν΄λ³΄μ.
μ μμ λ 맨 μ²μλΆν° λ²½μ λ«μ§ μλλ€. λ²½μ λ«κ±°λ λ«μ§ μμΌλ©΄μ N x M μμΉκΉμ§ κ°λ κ±°λ€.
Point(1, 1, 0) μ’νλ₯Ό νμνκ³ , Point(1, 2, 0) μ’νμ Point(2, 1, 0) μ’νλ₯Ό νμ λ£λλ€. κ·Έλ¦¬κ³ visited[1][2][0] = visited[2][1][0] = trueλ‘ λ°©λ¬Έ 체ν¬νλ€. μμ§ λ²½μ λ«μ μ μ΄ μμΌλ―λ‘ λ μ’ν λͺ¨λ 3λ²μ§Έ μΈμ(λ²½μ λ«μ νμ)λ 0μ΄μ΄κ³ λ²½μ λ«μ§ μκ³ μ΄λν κ²½λ‘μ 방문체ν¬ν΄μ£Όλ κ±°λ€.
λ€μ queueμ μ μΌ μμ μλ μ’νμΈ Point(1, 2, 0)λ₯Ό νμνμ. μ΄ λλ (1, 3)μ’νμ (2, 2)μ’νλ₯Ό νμν μ μλλ°, (1, 3)μ’νλ‘ μ΄λν κ²½μ°λ λ²½μ λ«μ§ μκ³ μ΄λν μ μκ³ , (2, 2)μ’νλ‘ μ΄λν λλ λ²½μ λ«μ΄μΌλ§ μ΄λ κ°λ₯ νλ€. Point(1, 2, 0) κ°μ 3λ²μ§Έ μΈμλ₯Ό ν΅ν΄ μ΄ κ²½λ‘λ λ²½μ λ«μ μ μ΄ μμΌλ―λ‘ λ μ’ν λͺ¨λ queueμ μ μ₯νλ€. μ΄ λ, (1, 3)μΌλ‘ μ΄λνλ κ²½λ‘λ λ²½μ λ«μ μ μμΌλ―λ‘ Point(1, 3, 0)μ κ°μ, (2, 2)λ‘ μ΄λνλ κ²½λ‘λ λ²½μ λ«μ΄μΌ νλ―λ‘ Point(2, 2, 1)λ‘ νν λ° queueμ μ μ₯νλ€. κ·Έλ¦¬κ³ visited[1][3][0] = visited[2][2][1] = true λ‘ κ°κ° λ²½μ λ«μ μ μμΌλ©΄μ λ°©λ¬Έν κ²½λ‘μ λ²½μ λ«μΌλ©΄μ λ°©λ¬Έν κ²½λ‘λ₯Ό 방문체ν¬ν΄μ€λ€.
λ€μ queueμ 맨 μμ κ°μΈ Point(2, 1, 0)μ νμνμ. Point(2, 1, 0)μ κ°μ 보면 μ μ μλμ μ§κΈκΉμ§ λ²½μ λ«μ μ μλ κ²½λ‘λ₯Ό μ μ₯ν κ²μ΄λ€. μμ§ λ²½μ λ«μ μ μ΄ μμΌλ―λ‘ (2, 2)μ’νμ (3,1)μ’ν λͺ¨λ κ°λ₯ν ν λ°, (2, 2) μ’νλ‘ μ΄λν κ²½μ° λ²½μ λ«μ μ μλ€λ νμλ₯Ό ν΄μ€μΌ νλ€. Point(2, 2, 1) μ΄λ κ². κ·Όλ° (2, 2, 1)μ μ΄λ―Έ (1, 2)μ’νμμ νμν λ visited[2][2][1] = trueλ‘ μ²΄ν¬ν΄μ£Όκ³ queueμ λ£μ΄μ€¬λ€. λ°λΌμ μ΄λ―Έ μ΄λ² κ²½λ‘μμλ Point(3, 1, 0)λ§ μ μ₯νκ³ λ²½μ λ«μ μ μμΌλ©΄μ λ°©λ¬Ένλ€λ νμλ‘ visited[3][1][0] = true λ‘ μ²΄ν¬ν΄μ€λ€.
κ·Έ λ€μμ Point(1,3,0)λ₯Ό νμνλ€. (1, 4) μ’νμ, (2, 3) μ’νλ₯Ό νμν ν λ°, (1, 4)μ’νλ λ²½μ΄ μλ κ²½λ‘λ₯Ό 체ν¬νλ λ°°μ΄μ 방문체ν¬ν΄μ£Όκ³ , (2, 3)μ’νλ λ²½μ λ«μ΄μΌ νλ―λ‘ λ²½μΈ κ²½λ‘λ₯Ό 체ν¬νλ λ°°μ΄μ 방문체ν¬ν΄μ€λ€. μ¦ visited[1][4][0] = visited[2][3][1] = trueμ΄κ³ , queueμ Point(1, 4, 0)κ³Ό Point(2, 3, 1) κ°μ΄ μ μ₯λλ€.
Point(2, 2, 1)μ λ²½μ λΆμ μ μλ μ΄λκ²½λ‘ μ΄λ―λ‘ visited[2][3][1] = visited[3][2][1]= trueλ‘ μ²΄ν¬ν΄μ£Όκ³ , Point(2, 3, 1)κ³Ό Point(3, 2, 1)μ queueμ λ£λλ€.
Point(3, 1, 0)μ λ²½μ λΆμ μ μλ μ΄λκ²½λ‘ μ΄λ―λ‘ visited[3][2][0] = visited[4][1][0] = trueλ‘ μ²΄ν¬ν΄μ£Όκ³ queueμ Point(3, 2, 0)κ³Ό Point(4, 1, 0)μ λ£μ΄μ€λ€.
μ¬κΈ°μ queueμ Point(3, 2, 1)κ³Ό Point(3, 2, 0)μ΄ μλ κ²μ΄ λ³΄μΌ κ²μ΄λ€. μ΄λ κ² λ²½μ λΆμλ©° νμνλ κ²½λ‘μ λ²½μ λΆμμ§ μκ³ νμνλ κ²½μ° λλ€λ₯Ό νμΈνκΈ° λλ¬Έμ λ λ€μ κ²½μ°μμ μ΅λ¨κ²½λ‘λ₯Ό νμ ν μ μλ κ²μ΄λ€.
κ·Έ λ€λ‘ μ κ³Όμ μ κ³μ λ°λ³΅νλ€.
queueμ κ°μ΄ λͺ¨λ λΉ μ§κ³ νμ¬ μ’νκ° (N,M)μ΄ λλ©΄ νμ¬κΉμ§ ꡬν κ²½λ‘κΈΈμ΄λ₯Ό λ°νν΄μ€λ€!
[μ½λ]
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int MAX_VALUE = 1001;
int direction[4][2] = { {0,1}, {1,0},{0,-1},{-1,0} };//μ΄λ λ°©ν₯ν€: μ€λ₯Έμͺ½, μλ, μΌμͺ½, μ
class Point {
public:
int x;
int y;
int breakCount;//λ²½μ λΆμ νμ. 0 or 1λ‘ νν
int count;//μ΄λ νμ. λμ€μ μΆλ ₯ν΄μ€μΌ ν¨.
Point(int x, int y, int breakCount, int count) {
this->x = x;
this->y = y;
this->breakCount = breakCount;
this->count = count;
}
};
int MoveByBFS(int N, int M, int map[MAX_VALUE][MAX_VALUE]);//BFSλ₯Ό ν΅ν μ΅λ¨κ±°λ¦¬ μ°ΎκΈ° μν
int main() {
int N, M;
cin >> N >> M;
int map[MAX_VALUE][MAX_VALUE] = { 0, };
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
scanf_s("%1d", &map[i][j]);
}
}
cout << MoveByBFS(N, M, map);
return 0;
}
int MoveByBFS(int N, int M, int map[MAX_VALUE][MAX_VALUE]) {
queue<Point> q;
bool visited[MAX_VALUE][MAX_VALUE][2] = { false, };
q.push(Point(0,0,0,1));
visited[0][0][0] = true;//λ²½μ λΆμ νμκ° 0μ΄λ©΄μ ν΄λΉ μ’νμ λ°©λ¬Ένμμ λνλ
visited[0][0][1] = true;//λ²½μ λΆμ νμκ° 1μ΄λ©΄μ ν΄λΉ μ’νμ λ°©λ¬Ένμμ λνλ
while (!q.empty()) {
Point currentPoint = q.front();
q.pop();
if (currentPoint.x == N - 1 && currentPoint.y == M - 1) {
return currentPoint.count;
}
for (int i = 0; i < 4; i++) {
int nx = currentPoint.x + direction[i][0];
int ny = currentPoint.y + direction[i][1];
if (nx < N && nx >= 0 && ny < M && ny >= 0) {
if (!visited[nx][ny][0]) {//λ²½ λΆμ νμκ° 0μ΄λ©΄μ ν΄λΉ μ’νμ λ°©λ¬Έν μ μ΄ μλ κ²½μ°
if (map[nx][ny] == 0 && currentPoint.breakCount == 0) {//ν΄λΉ μ’νμ λ²½μ΄ μκ³ μ΄μ κΉμ§ λ²½ λΆμ νμλ 0μΌ κ²½μ°λ§ push
visited[nx][ny][0] = true;
q.push(Point(nx, ny, 0, currentPoint.count + 1));
}
}
if (!visited[nx][ny][1]) {//λ²½ λΆμ νμκ° 1μ΄λ©΄μ ν΄λΉ μ’νμ λ°©λ¬Έν μ μ΄ μλ κ²½μ°
if ((map[nx][ny] == 1 && currentPoint.breakCount == 0)//ν΄λΉ μ’νμ λ²½μ΄ μκ³ λ²½ λΆμ νμκ° 0μΈ κ²½μ°
|| (map[nx][ny] == 0 && currentPoint.breakCount == 1)) {//or ν΄λΉ μ’νμ λ²½μ΄ μκ³ λ²½ λΆμ νμκ° 1μΈ κ²½μ°
visited[nx][ny][1] = true;
q.push(Point(nx, ny, 1, currentPoint.count + 1));
}
}
}
}
}
return -1;
}