Coding Test/C++
[완전탐색 / BOJ 1189 / C++] 컴백홈
코드진행형
2023. 3. 8. 00:06
https://www.acmicpc.net/problem/1189
1189번: 컴백홈
첫 줄에 정수 R(1 ≤ R ≤ 5), C(1 ≤ C ≤ 5), K(1 ≤ K ≤ R×C)가 공백으로 구분되어 주어진다. 두 번째부터 R+1번째 줄까지는 R×C 맵의 정보를 나타내는 '.'과 'T'로 구성된 길이가 C인 문자열이 주어진다
www.acmicpc.net
1) find_rt함수를 재귀적으로 실행해준다. (bfs나 dfs처럼 동작)
1-1) base 조건은 x,y가 목적지에 도달했고 여기까지 온 비용이 K와 동일할때 1를 리턴한다.
1-2) 비용이 K와 동일하지 않다면, 0을 리턴한다.
1-3) 목적지에 아직 도달하지 않았다면, 목적지까지 네 방향으로 순회한다.
난 먼가 어려웠다... bfs나 dfs는 공식대로 하면 다 해결됐는데 이건 bfs이면서 아니라서 아이디어가 잘 떠오르지 않았다..
이 문제의 가장 중요한 것은 bfs를 돌면서, 만약 목적지에 도달했다면 리턴해주고 목적지까지 도달하기 까지 지나온
장소들의 방문을 모두 해제하는 것이다. (엄밀히말하면 bfs는 아니다)
그렇게해서, 다른 경우의 수도 세줄 수 있는 것이다.
또한 함수는 void형이 아닌 int형을 리턴한다!!!
이를 통해서 계속해서 개수를 갱신해나갈 수 있다. 이건 이전에 풀었던 문제들과 맥락이 비슷하다.
#include <bits/stdc++.h>
using namespace std;
int R, C, K;
string s;
char bd[26][26];
int vis[26][26];
int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, -1, 0, 1};
int find_rt(int y, int x){
if(y==0 && x==C-1) {
if(K==vis[y][x]) return 1;
return 0;
} // vis[y][x]가 K이고 끝점 도달시 1 리턴하고 종료 (아니면 0)
int cnt = 0; // 개수 초기화.
for(int i = 0 ; i < 4 ; i++){
int ny = y + dy[i];
int nx = x + dx[i];
if(ny >= R || nx >= C || ny < 0 || nx < 0 || bd[ny][nx]=='T' || vis[ny][nx]) continue; // 불가 조건이면 종료
vis[ny][nx] = vis[y][x] + 1;
cnt += find_rt(ny, nx); // 개수 세기
vis[ny][nx] = 0; // vis풀어주기 (다음 경우의 수 세기 위해서)
}
return cnt;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> R >> C >> K;
for(int i = 0 ; i < R ; i++){
cin >> s;
for(int j = 0 ; j < C ; j++){
bd[i][j] = s[j];
}
}
vis[R-1][0]=1;
cout << find_rt(R-1, 0);
}