Skip to content

Commit c66d5f4

Browse files
committed
[Gold III] Title: 게임 닉네임, Time: 364 ms, Memory: 118008 KB -BaekjoonHub
1 parent 49d5e83 commit c66d5f4

2 files changed

Lines changed: 130 additions & 0 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# [Gold III] 게임 닉네임 - 16934
2+
3+
[문제 링크](https://www.acmicpc.net/problem/16934)
4+
5+
### 성능 요약
6+
7+
메모리: 118008 KB, 시간: 364 ms
8+
9+
### 분류
10+
11+
자료 구조, 문자열, 트리, 집합과 맵, 해시를 사용한 집합과 맵, 트라이
12+
13+
### 제출 일자
14+
15+
2025년 9월 10일 13:09:10
16+
17+
### 문제 설명
18+
19+
<p>스타트링크에서 매우 재미있는 게임을 만들었다. 이 게임은 정말 재미있다.</p>
20+
21+
<p>게임에는 유저가 접속하는 기능이 있고, 각 유저는 가입할 때, 자신의 닉네임을 정해야 한다. 닉네임은 알파벳 소문자로만 이루어져 있고, 두 유저가 같은 닉네임을 정하는 것도 가능하다.</p>
22+
23+
<p>이 게임은 유저의 닉네임을 이용해서 내부에 저장할 별칭을 만든다. 별칭은 유저에게 보여지지는 않고, 내부에서만 사용된다. 저장 공간을 최소로 하기 위해서 별칭의 길이를 최소로 하려고 한다.</p>
24+
25+
<p>별칭은 유저 닉네임의 접두사(Prefix) 중에서 가장 길이가 짧은 것을 사용한다. 이때, 접두사가 이전에 가입한 닉네임의 접두사가 아니어야 한다. 가능한 별칭이 없는 경우에는 유저가 가입한 시점까지 같은 닉네임으로 가입한 사람의 수 x를 계산해야 한다. x가 1인 경우에는 닉네임을 별칭으로 사용하고, x가 2 이상인 경우에는 닉네임의 뒤에 x를 붙여서 별칭으로 사용한다.</p>
26+
27+
<p>예를 들어, 닉네임을 "baekjoon"으로 정한 유저가 가입하면, 이 유저의 별칭은 "b"가 된다. </p>
28+
29+
<p>그 다음, 닉네임이 "startlink"로 정한 유저가 가입하면, 이 유저의 별칭은 "s"이다. "bakejoon"이 닉네임인 유저가 가입하면, 별칭은 "bak"가 되고, "beakjoon"인 유저가 가입하면, 별칭은 "be"가 된다. 마지막으로 "baekjoon"으로 유저가 가입하면 별칭은 "baekjoon2"가 된다.</p>
30+
31+
<p>유저가 가입한 순서대로 닉네임이 주어졌을 때, 각 유저의 별칭을 구해보자. 위의 규칙을 이용해 별칭을 정하면 두 유저가 같은 별칭을 갖는 것도 가능하다.</p>
32+
33+
### 입력
34+
35+
<p>첫째 줄에 가입한 유저의 수 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 유저의 닉네임이 가입한 순서대로 한 줄에 하나씩 주어진다. 닉네임은 알파벳 소문자로만 이루어져 있고, 길이는 10을 넘지 않는다.</p>
36+
37+
### 출력
38+
39+
<p>유저가 가입한 순서대로 별칭을 한 줄에 하나씩 출력한다.</p>
40+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
final class Trie<T: BidirectionalCollection> where T.Element: Hashable {
2+
class Node {
3+
var childList = [T.Element: Node]()
4+
var endOfWord: Bool
5+
6+
init(_ _endOfWord: Bool) {
7+
endOfWord = _endOfWord
8+
}
9+
10+
func hasChild(for c: T.Element) -> Node? {
11+
return childList[c]
12+
}
13+
func addChild(for key: T.Element) -> Node {
14+
let child = Node(false)
15+
childList.updateValue(child, forKey: key)
16+
return child
17+
}
18+
}
19+
20+
let root = Node(false)
21+
22+
func insert(_ word: T) -> [T.Element] {
23+
var prefix = [T.Element]()
24+
var isShortestPrefix = true
25+
// 단어를 입력받는다.
26+
// 단어의 알파벳을 순회하며
27+
// 루트노드 부터 해당 알파벳이 존재한다면
28+
// 그냥 쭉쭉 그 노드로 넘기고 현재 탐색 노드를 그 노드의 해당 자식 노드로 교체
29+
// 존재하지 않는다면, 탐색중인 노드에 새 자식 노드를 등록하고 해당 자식 노드로 교체
30+
var currentNode = root
31+
for c in word {
32+
if let child = currentNode.hasChild(for: c) {
33+
prefix.append(c)
34+
currentNode = child
35+
continue
36+
}
37+
currentNode = currentNode.addChild(for: c)
38+
guard isShortestPrefix else { continue }
39+
prefix.append(c)
40+
isShortestPrefix = false
41+
}
42+
currentNode.endOfWord = true
43+
44+
return prefix
45+
}
46+
47+
func contains(_ target: T) -> Bool {
48+
var currentNode = root
49+
for element in target {
50+
guard let nextNode = currentNode.hasChild(for: element) else { return false }
51+
currentNode = nextNode
52+
}
53+
return currentNode.endOfWord
54+
}
55+
56+
@discardableResult
57+
func delete(_ target: T) -> Bool {
58+
var currentNode = root
59+
// 삭제할 대상의 마지막 문자열 노드까지 내려감
60+
for element in target {
61+
guard let nextNode = currentNode.hasChild(for: element) else { return false }
62+
currentNode = nextNode
63+
}
64+
// 마지막 노드까지 내려갔는데, 대상의 끝이 아니라면 삭제 불가
65+
guard currentNode.endOfWord else { return false }
66+
currentNode.endOfWord = false
67+
return true
68+
}
69+
}
70+
71+
72+
let n = Int(readLine()!)!
73+
let trie = Trie<String>()
74+
var wordCountMap = [String: Int]()
75+
76+
var answer = ""
77+
78+
for _ in 0..<n {
79+
let word = readLine()!
80+
let nickName = trie.insert(word)
81+
if let count = wordCountMap[word] {
82+
wordCountMap[word]! += 1
83+
answer.write(word + "\(count+1)\n")
84+
} else {
85+
wordCountMap[word] = 1
86+
answer.write(String(nickName)+"\n")
87+
}
88+
}
89+
90+
print(answer)

0 commit comments

Comments
 (0)