10000 Merge pull request #407 from hehehwang/0x1F-5670 · REDICALED/basic-algo-lecture@d39f5bd · GitHub
[go: up one dir, main page]

Skip to content

Commit d39f5bd

Browse files
Merge pull request encrypted-def#407 from hehehwang/0x1F-5670
0x1F(트라이) Update 5670.cpp
2 parents 3a66de9 + 80c7ca7 commit d39f5bd

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

0x1F/solutions/5670.cpp

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,71 @@
1-
// Authored by : BaaaaaaaaaaarkingDog
1+
// Authored by : heheHwang
22
// Co-authored by : -
3-
// http://boj.kr/****************
3+
// http://boj.kr/d335d203808e47d5a4f5f7dbe17ecdfb
44
#include <bits/stdc++.h>
55
using namespace std;
66

7-
int main(void){
7+
const int ROOT = 1, MX = 1e6 + 10;
8+
int unused, keystroke_total;
9+
bool chk[MX];
10+
vector<pair<int, int>> nxt[MX]; // 자식을 동적 배열로 관리
11+
12+
// node의 자손 중, c에 해당하는 자손이 있는지 체크합니다.
13+
int getchild(int node, char c) {
14+
for (auto [id, c_] : nxt[node])
15+
if (c == c_) return id;
16+
return -1;
17+
}
18+
void insert(string& s) {
19+
int curr = ROOT;
20+
for (auto c : s) {
21+
int child = getchild(curr, c);
22+
if (child == -1) {
23+
child = unused;
24+
nxt[curr].push_back({unused++, c});
25+
}
26+
curr = child;
27+
}
28+
chk[curr] = true;
29+
}
30+
// dfs 탐색
31+
void dfs(int curr, int key_strokes) {
32+
if (chk[curr])
33+
keystroke_total += ++key_strokes;
34+
else if (nxt[curr].size() > 1)
35+
++key_strokes;
36+
for (auto [nxt_node, _] : nxt[curr])
37+
dfs(nxt_node, key_strokes);
38+
}
39+
int main(void) {
840
ios::sync_with_stdio(0);
941
cin.tie(0);
10-
11-
}
42+
cout << fixed;
43+
cout.precision(2);
44+
45+
int N;
46+
while (cin >> N) {
47+
for (int i = 0; i < MX; i++) nxt[i].clear();
48+
fill(chk, chk + MX, 0);
49+
unused = ROOT + 1;
50+
keystroke_total = 0;
51+
52+
vector<string> words(N);
53+
for (int i = 0; i < N; i++) cin >> words[i];
54+
for (auto& s : words) insert(s);
55+
for (auto [id, _] : nxt[ROOT]) dfs(id, 0);
56+
cout << 1.0 * keystroke_total / words.size() << '\n';
57+
}
58+
}
59+
/*
60+
자판을 누르는 행위는 다음과 같은 경우에 이루어집니다.
61+
1. 단어 분기가 존재할 경우
62+
2. 단어가 완성되었을 경우
63+
이 두가지 경우에 맞추어서 적절하게 카운터를 올려주면서
64+
탐색해주면 자판을 누르는 횟수를 계산할 수 있습니다.
65+
66+
유의점: 처음 한 번은 무조건 누르게 되어있으므로,
67+
ROOT의 각 자식에서부터 탐색을 시작해야 합니다.
68+
69+
메모리 절약을 위해 동적 배열로 구현했지만 자식을 26칸 배열로 두어도
70+
아마 통과에는 문제가 없을 것입니다.
71+
*/

0 commit comments

Comments
 (0)
0