9944번: NxM 보드 완주하기
N×M 보드 위에서 할 수 있는 게임이 있다. 보드는 크기가 1×1인 정사각형 칸으로 나누어져 있다. 보드의 각 칸은 빈 칸 또는 장애물이다. 장애물은 아래 그림에선 어두운 사각형으로 표시되어져
www.acmicpc.net
1. 접근
공이 방향을 전환하는 분기가 있고, 각 분기로 나누어진 경우마다 모든 map을 탐색할 수 있는지를 알아야하기 때문에 dfs를 생각했다.
모든 맵을 탐색했는지 확인하기 위해서
1) 더 이상 못움직이는 경우 모든 맵을 탐색했는지 반복문으로 확인하여 결과 도출
2) map을 입력 받을 때 탐색할 수 있는 공간의 개수를 따로 저장해서 활용하여 결과 도출
두 가지를 생각했는데 2번째 방식이 가독성, 시간 면에서 조금 더 낫다고 생각해서 2번째 방식을 선택했다.
2. 풀이과정
재귀마다 4가지 방향을 본 뒤 도달할 수 있는 방향까지 check하고 다음 재귀, 재귀 후 uncheck하는 방식으로 구현했다.
3번이나 틀리고나서야 출력에 띄어쓰기를 안해서 틀렸다는 걸 알았다..
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
using namespace std;
int T, N, M, K;
char map[31][31];
bool chk[31][31] = { false, };
pair<int, int> dir[4] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } };
int ans;
void dfs(int y, int x, int cnt, int k){
// 조금이나마 시간 줄이기
if (ans < cnt)
return;
// 모두 탐색한 경우에 ans 갱신
if (k == 0){
if (ans > cnt)
ans = cnt;
return;
}
for (int i = 0; i < 4; i++){
int ny = y + dir[i].first, nx = x + dir[i].second;
int nk = k;
// 현재 방향으로 탐색할 수 있을 때 까지 탐색
while (ny >= 0 && ny < N && nx >= 0 && nx < M && map[ny][nx] == '.' && !chk[ny][nx]){
chk[ny][nx] = true;
nk--;
ny += dir[i].first;
nx += dir[i].second;
}
ny -= dir[i].first;
nx -= dir[i].second;
if (ny != y || nx != x){
dfs(ny, nx, cnt + 1, nk);
// 이번 반복문에서 탐색한 영역 되돌리기
while (ny != y || nx != x){
chk[ny][nx] = false;
ny -= dir[i].first;
nx -= dir[i].second;
}
}
}
return;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
T = 0;
while (cin >> N >> M){
// init
ans = INT_MAX;
K = 0;
memset(chk, false, sizeof(chk));
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++){
cin >> map[i][j];
if (map[i][j] == '.')
K++; // 탐색되어야할 공간의 수
}
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (map[i][j] == '.'){
chk[i][j] = true;
dfs(i, j, 0, K - 1); // 재귀 시작
chk[i][j] = false;
}
if (ans == INT_MAX)
cout << "Case " << ++T << ": " << -1 << "\n";
else
cout << "Case " << ++T << ": " << ans << "\n";
}
return 0;
}
'알고리즘 > 알고리즘' 카테고리의 다른 글
[C++]백준 13913번 : 숨바꼭질4 (0) | 2020.12.04 |
---|---|
[C++]백준 1261번 : 알고스팟 (0) | 2020.12.04 |
[C++]백준 16137번 : 견우와 직녀 (0) | 2020.12.01 |
[C++]백준 16986번 : 인싸들의 가위바위보 (0) | 2020.11.30 |
[C++]백준 10836번 : 여왕벌 (0) | 2020.11.30 |