https://www.acmicpc.net/problem/31404
분리집합으로 풀어야 하나 했는데 사이클을 어떻게 잡아야 할지 감이 안오고, 입력값들의 범위가 딱 봐도 구현이길래 구현만 하자라는 마인드로 풀었다.
먼지를 청소했을때는 ruleA를 따르고, 아닐때는 ruleB를 따르며 움직여야 한다. 3차원 배열을 이용해서 특정 위치 (r,c)에 들어가는 방향이 같은 경우 사이클이 생기므로 반복을 종료하면 된다.
또 중요한 건 먼지를 치웠을 때 사이클 확인을 위해 저장해놓은 3차원 배열을 모두 처음 상태로 초기화 시켜주어야 한다. ruleA와 ruleB가 다르기 때문에 같은 방향으로 들어가더라도 다음 이동이 달라질 수 있기 때문이다.
개인적으로 어려웠던 문제다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#define endl "\n"
#define ll long long
#define pii pair<int,int>
using namespace std;
bool dust[65][65];
bool cache[65][65][4];
int ruleA[65][65];
int ruleB[65][65];
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int H,W,r,c,d;
int clearCache(){
for(int i = 0; i < H; i++){
for(int j = 0; j < W; j++){
for(int k = 0; k < 4; k++){
cache[i][j][k] = false;
}
}
}
return 0;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
string s;
cin >> H >> W >> r >> c >> d;
for(int i = 0; i < H; i++){
cin >> s;
for(int j = 0; j < W; j++){
ruleA[i][j] = s[j]-'0';
}
}
for(int i = 0; i < H; i++){
cin >> s;
for(int j = 0; j < W; j++){
ruleB[i][j] = s[j] - '0';
}
}
int cnt = 0, ans = 0;
while(true){
if(r<0 || r>=H || c<0 || c>=W) break;
if(cache[r][c][d]) break;
if(dust[r][c]) {
cache[r][c][d] = true;
d = (d+ruleB[r][c])%4;
}
else {
clearCache();
dust[r][c] = true;
d = (d+ruleA[r][c])%4;
ans = cnt;
}
r += dx[d], c += dy[d];
cnt++;
}
cout << ans+1;
}
'📚알고리즘 > 백준' 카테고리의 다른 글
[백준 24025번] 돌의 정령 줄세우기 (C++) (0) | 2024.07.16 |
---|---|
[백준 7561번] 크래머의 공식 (C++) (0) | 2024.07.06 |
[백준 2206번] 벽 부수고 이동하기 (C++) (0) | 2024.07.03 |
[백준 1437번] 수 분해 (C++) (0) | 2024.06.23 |
[백준 28703번] Double it (C++) (0) | 2024.06.23 |