문제 링크 : www.acmicpc.net/problem/1103
게임을 무한히 할 수 있는 경우는 어떤 경우일까?
일련의 순서로 각 칸을 방문할 때, 이미 한 번 방문했던 칸을 다시 방문할 수 있다면 게임을 무한히 진행할 수 있다.
즉, 게임판 내에서 사이클이 발생하는 경우이다.
따라서, 제시된 2차원 배열의 각 칸을 정점으로 하는 그래프를 구성한 후
1번 정점으로부터 시작해 백트래킹을 통해 최대로 갈 수 있는 거리를 구하면 된다.
(이 과정에서 사이클을 발견한다면, 바로 -1을 출력한다.)
단, 각 정점마다 그 정점에 도달하기까지 거쳐온 최대 정점 수를 기록해 그보다 같거나 적은 값을 통해 도달했을 시 더 이상 탐색하지 않도록 가지치기를 해 주어야 시간 초과를 피할 수 있다.
[코드]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
typedef pair<int, int> p;
typedef long long ll;
p dir[4] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} };
int n, m, answer;
int board[51][51];
vector<int> adj[2501];
int maxdist[2501];
bool visit[2501], cycle = false;
void dfs(int node, int cnt) {
//dfs 백트래킹
if (cycle) return;
visit[node] = true;
answer = max(answer, cnt);
for (int i = 0; i < adj[node].size(); i++) {
int nextnode = adj[node][i];
if (visit[nextnode]) {
cycle = true; //사이클 판별
return;
}
if(maxdist[nextnode] >= cnt + 1) continue;
maxdist[nextnode] = cnt + 1;
dfs(nextnode, cnt + 1);
}
visit[node] = false;
}
void set_adj(int row, int col) {
if (board[row][col] == -1) return;
int node = (row - 1) * m + col;
for (int i = 0; i < 4; i++) {
int newR = row + dir[i].first * board[row][col];
int newC = col + dir[i].second * board[row][col];
if (newR < 1 || newR > n || newC < 1 || newC > m) continue;
if (board[newR][newC] == -1) continue;
int nextnode = (newR - 1) * m + newC;
adj[node].push_back(nextnode);
}
}
void init() {
string input;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> input;
for (int j = 1; j <= m; j++) {
if (input[j - 1] == 'H') board[i][j] = -1;
else board[i][j] = input[j - 1] - '0';
}
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
set_adj(i, j);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(NULL);
init();
dfs(1, 0);
if (cycle) printf("-1\n");
else printf("%d\n", answer + 1);
//system("PAUSE");
return 0;
}
|
cs |
'알고리즘 > BOJ 문제풀이' 카테고리의 다른 글
[LCA] BOJ 3176 도로 네트워크 (2) | 2021.01.28 |
---|---|
[LCA] BOJ 1761 정점들의 거리 (0) | 2021.01.28 |
[DFS] BOJ 2001 보석 줍기 (1) | 2021.01.25 |
[MST] BOJ 4792 레드 블루 스패닝 트리 (2) | 2021.01.24 |
[Tree/DP] BOJ 2213 트리의 독립집합 (0) | 2021.01.23 |