반응형

문제 출처 :


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



알고리즘 분석 :


문제 해결에 필요한 사항

1. 트라이


이 문제는 트라이와 8방향 탐색을 이용하여 문제를 해결 할 수 있다.


우선 첫 인풋으로 들어오는 문자열들을 트라이에 넣어준다.


그 뒤 4 * 4로 들어오는 인풋에 대해 8방향 탐색을 하여 만들 수 있는 최대 8자리 문자열을 다 만들어보고 트라이에서 탐색해본다.


이때 트라이에 문자열이 존재하고(isEnd == true) 아직 이 문자열로 만들어낸 적이 없었다면(isVisited != tc)  해당하는 문자열을 정답에 갱신해주면 된다.







소스 코드 : 


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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <memory.h>
 
using namespace std;
 
const int NODE = 26;
 
int dy[8= { -1,-1,-1,0,0,1,1,};
int dx[8= { -1,0,1,-1,1,-1,0,};
 
char arr[10][10];
bool visit[10][10];
string maxStr;
int maxCnt, sz, total;
int tc;
struct TRIE {
    TRIE *next[NODE];
    bool isEnd;
    int isVisited;
 
    TRIE() {
        for (int i = 0; i < NODE; i++)
            next[i] = nullptr;
        isEnd = isVisited = false;
    }
    ~TRIE() {
        for (int i = 0; i < NODE; i++)
            if (next[i])
                delete next[i];
    }
};
 
bool chkRange(int y, int x)
{
    return ((<= x && x < 4&& (<= y && y < 4)) ? true : false;
}
 
void go(int y, int x, int cnt, TRIE *cur, string str) {
 
    int nowCh = arr[y][x] - 'A';
    //cout << "y :: " << y << " x ::" << x << " cnt :: " << cnt << " str :: " << str << endl;
    //    cout << "nowCh :: " << (char)(nowCh + 'A')  << endl;
    if (cnt == || !cur->next[nowCh])
        return;
    if (cur->next[nowCh]->isEnd && cur->next[nowCh]->isVisited != tc)
    {
        cur->next[nowCh]->isVisited = tc;
        if (cnt + == || cnt + == 4)
            total += 1;
        else if (cnt + == 5)
            total += 2;
        else if (cnt + == 6)
            total += 3;
        else if (cnt + == 7)
            total += 5;
        else if (cnt + == 8)
            total += 11;
 
        sz++;
        if (cnt + > maxCnt) {
            maxStr = str + (char)(nowCh + 'A');
            maxCnt = cnt + 1;
        }
        else if (cnt + == maxCnt) 
            if (maxStr > (str + (char)(nowCh + 'A')))
                maxStr = str + (char)(nowCh + 'A');
    }
 
    for (int i = 0; i < 8; i++)
    {
        int ny = y + dy[i];
        int nx = x + dx[i];
        if (!chkRange(ny, nx) || visit[ny][nx])
            continue;
 
        visit[y][x] = true;
        str += arr[y][x];
        go(ny, nx, cnt + 1, cur->next[nowCh], str);
        visit[y][x] = false;
        str.pop_back();
    }
 
}
 
int _strlen(char *tmp) {
    int len = 0;
    while (tmp[++len]) {}
    return len;
}
 
TRIE *root;
int main()
{
    root = new TRIE;
 
    int n;
    scanf("%d"&n);
 
    for (int i = 0; i < n; i++)
    {
        char tmp[10];
        scanf("%s", tmp);
 
        TRIE *pos = root;
        for (int i = 0; tmp[i]; i++) {
            int nowCh = tmp[i] - 'A';
 
            if (!pos->next[nowCh])
                pos->next[nowCh] = new TRIE;
 
            pos = pos->next[nowCh];
        }
 
        pos->isEnd = true;
    }
 
    int m;
    scanf("%d"&m);
 
    for(tc = 1; tc <= m; tc++)
    {
        memset(visit, 0sizeof(visit));
        sz = maxCnt = total = 0;
        maxStr.clear();
 
        for (int i = 0; i < 4; i++)
            scanf("%s", arr[i]);
    
        for(int i = ; i < 4; i++)
            for (int j = 0; j < 4; j++)
            {
                int nowCh = arr[i][j] - 'A';
                if(root->next[nowCh])
                    go(i, j, 0, root, "");
            }
        cout << total << " " << maxStr << " " << sz << endl;
    }
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[1342번] 행운의 문자열  (0) 2018.03.17
[CSAcademy] Prefix Free Subset  (4) 2018.03.11
[5446번] 용량 부족  (0) 2018.03.08
[1744번] 수 묶기  (0) 2018.03.08
[13717번] 포켓몬 GO  (0) 2018.03.07