algorithm/BOJ

BOJ 9202번 Boggle

_JunHo 2020. 2. 5. 22:12

BOJ : https://www.acmicpc.net/problem/9202

github : https://github.com/junho0956/Algorithm/blob/master/9202/9202/%EC%86%8C%EC%8A%A4.cpp

 

2가지 방법으로 해결했습니다.

trie 자료구조 복습겸 작성해봤고, trie 없이 dfs 하는 방식으로 해봤습니다.

 

trie 자료구조를 이용한 방법

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//Boggle
 //일반적인 DFS 문제인데 현재 탐색을 기준 문자열이 존재하는지 없는지 확인하는 작업이 필요하다
 //DFS의 탐색때 마다 모든 문자열을 확인 작업하게되면 TLE가 될 것이다
 //문자열을 빠르게 찾기 위해서는 수업시간에 배운 trie 자료구조를 사용해야한다.
 //문자트리 라고 생각하면 된다
 
#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <set>
using namespace std;
 
ifstream fcin("large_hand.in");
ofstream fcout("large_hand.out");
 
int w, b;
int visit[4][4];
string board[4];
set<string> key;
int score[9= { 0,0,0,1,1,2,3,5,11 };
int my[8= { -1,-1,-1,0,0,1,1,1 };
int mx[8= { -1,0,1,-1,1,-1,0,1 };
 
struct trie {
    // 알파벳A~Z까지에 대한 배열
    trie* node[26];
    // 단어의 종료를 알리는 배열
    bool finish;
 
    // new 를 위한 생성자
    trie() {
        memset(this->node, NULLsizeof(this->node));
        this->finish = false;
    }
 
    // 스트링에 대한 트라이트리 만들기
    // 현재 포인터에 대한 다음 포인터가 없다면 연결을 위해 만들어준다
    void insert(string s) {
        trie* p = this;
        for (int i = 0; i < s.length(); i++) {
            int index = s[i] - 'A';
            if (p->node[index] == NULL)
                p->node[index] = new trie();
            p = p->node[index];
        }
        // 단어의 종료를 알려줘야한다
        p->finish = true;
    }
 
    void search(int y, int x, string s) {
        // 단어가 8글자이하라고 했다
        if (s.length() > 8return;
 
        visit[y][x] = 1;
        s += board[y][x];
 
        trie* check = this->node[board[y][x] - 'A'];
        // 현재 포인터에 대해 방금 추가한 단어가 없다 -> 연결안되있다면 반환
        if (check == NULL) {
            visit[y][x] = 0;
            return;
        }
 
        // 중복처리를 위해 set 처리
        if (check->finish) key.insert(s);
 
        for (int i = 0; i < 8; i++) {
            int yy = y + my[i];
            int xx = x + mx[i];
            if (yy >= 0 && yy < 4 && xx >= 0 && xx < 4 && visit[yy][xx] == 0) {
                check->search(yy, xx, s);
            }
        }
        // dfs 에 의한 방문처리
        visit[y][x] = 0;
    }
};
 
int main() {
    ios::sync_with_stdio(0), fcin.tie(0), fcout.tie(0);
 
    // trie의 루트노드
    trie* root = new trie();
 
    fcin >> w;
    while (w--) {
        string str;
        fcin >> str;
        // 단어추가
        root->insert(str);
    }
 
    fcin >> b;
    while (b--) {
        key.clear();
        for (int i = 0; i < 4; i++)
            fcin >> board[i];
 
        // 0.0 부터 3.3 까지 전부 탐색해준다
        for (int i = 0; i < 4; i++)
            for (int j = 0; j < 4; j++)
                root->search(i, j, "");
 
        string longstr = "";
        int total = 0, findNum = key.size();
        for (string po : key) {
            total += score[po.length()];
 
            if (longstr.length() == po.length())
                longstr = longstr < po ? longstr : po;
            else if (longstr.length() < po.length())
                longstr = po;
        }
 
        fcout << total << " " << longstr << " " << findNum << "\n";
    }
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

 

trie 없이 기본 dfs 로만 구현

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
#include <iostream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
 
int w, b;
string board[4];
bool visit[4][4], isFind;
string isWant;
set<string> key;
int score[9= { 0,0,0,1,1,2,3,5,11 };
int my[8= { -1,-1,-1,0,0,1,1,1 };
int mx[8= { -1,0,1,-1,1,-1,0,1 };
string v[300001];
 
void search(int y, int x, int index) {
    if (isFind || index >= isWant.size()) return;
    if (isWant[index] != board[y][x]) return;
 
    visit[y][x] = true;
 
    if (index == isWant.size() - 1 && board[y][x] == isWant[index]) {
        key.insert(isWant);
        isFind = true;
        visit[y][x] = false;
        return;
    }
 
    for (int i = 0; i < 8; i++) {
        int yy = y + my[i];
        int xx = x + mx[i];
        if (yy >= 0 && yy < 4 && xx >= 0 && xx < 4 && visit[yy][xx] == 0) {
            search(yy, xx, index + 1);
            if (isFind) {
                visit[y][x] = false;
                return;
            }
        }
    }
 
    visit[y][x] = false;
}
 
int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
 
    cin >> w;
    for (int i = 0; i < w; i++cin >> v[i];
 
    cin >> b;
    while (b--) {
        key.clear();
        for (int i = 0; i < 4; i++)
            cin >> board[i];
        for (int k = 0; k < w; k++) {
            bool t = false;
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (board[i][j] == v[k][0]) {
                        isFind = false;
                        isWant = v[k];
                        int num = key.size();
                        search(i, j, 0);
                        if (num != key.size()) { t = truebreak; }
                    }
                }
                if (t) break;
            }
        }
        string longest = "";
        int total = 0, cnt = key.size();
        for (string at : key) {
            if (longest.length() == at.length())
                longest = longest < at ? longest : at;
            else if (longest.length() < at.length())
                longest = at;
            total += score[at.length()];
        }
        cout << total << " " << longest << " " << cnt << "\n";
    }
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter