알고리즘/BOJ 문제풀이

[DFS] BOJ 1103 게임

4Legs 2021. 1. 25. 22:47

문제 링크 : www.acmicpc.net/problem/1103

 

1103번: 게임

줄에 보드의 세로 크기 N과 가로 크기 M이 주어진다. 이 값은 모두 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 보드의 상태가 주어진다. 쓰여 있는 숫자는 1부터 9까지의 자연수 또는

www.acmicpc.net

게임을 무한히 할 수 있는 경우는 어떤 경우일까?

일련의 순서로 각 칸을 방문할 때, 이미 한 번 방문했던 칸을 다시 방문할 수 있다면 게임을 무한히 진행할 수 있다.

즉, 게임판 내에서 사이클이 발생하는 경우이다.

 

따라서, 제시된 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<intint> p;
typedef long long ll;
 
p dir[4= { {-10}, {01}, {10}, {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 + 1continue;
        maxdist[nextnode] = cnt + 1;
        dfs(nextnode, cnt + 1);
    }
 
    visit[node] = false;
}
 
void set_adj(int row, int col) {
    if (board[row][col] == -1return;
    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] == -1continue;
 
        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(10);
    if (cycle) printf("-1\n");
    else printf("%d\n", answer + 1);
 
    //system("PAUSE");
    return 0;
}
 
cs