게임판의 상태가 주어졌을 때, 사이클이 존재하는지 아닌지 구해보자.
4
이상이면 사이클이 있다고 판단한다.1
이다.5번째 호출
된 지점이며 이는 곧 거리가 5
임을 의미한다.4
이상이므로 사이클을 이룸을 알 수 있다.#include <iostream>
#include <cstring>
using namespace std;
static int N, M;
static char map[51][51];
static bool isVisited[51][51];
static constexpr int d[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
inline bool isPossible(int y, int x) {
return (0 <= y && y < N) && (0 <= x && x < M);
}
bool solve(int y, int x, int py, int px) {
if (isVisited[y][x]) return true; // 사이클이 형성됐다면 true를 반환한다.
isVisited[y][x] = true; // 방문 표시한다.
for (int i = 0; i < 4; ++i) { // 상하좌우 네 방향에 대해 탐색한다.
int ny = y + d[i][0], nx = x + d[i][1];
// 1) 범위 내에 있는 점이고, 2) 이전에 방문한 점이 아니며, 3) 같은 색상이라면 전진.
if (isPossible(ny, nx) && !(ny == py && nx == px) && map[ny][nx] == map[y][x])
if (solve(ny, nx, y, x)) return true;
}
return false;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> N >> M;
for (int i = 0; i < N; ++i) cin >> map[i]; // char 배열 입력은 이렇게도 받을 수 있다!
for (int y = 0; y < N; ++y)
for (int x = 0; x < M; ++x) { // 모든 점에 대해 DFS를 수행한다.
if (isVisited[y][x]) continue; // 이미 방문한 점이라면 DFS 수행 불필요.
memset(isVisited, false, sizeof(isVisited));
if (solve(y, x, y, x)) {
cout << "Yes\n";
return 0;
}
}
cout << "No\n";
return 0;
}