BOJ 5052. 전화번호 목록
1. 문제설명
- 문자열로 구성된 번호가 주어진다.
-
만약 어떤 문자열이 다른 문자열의 접두어가 되면 안된다.
- 문제 분류
- Data Structure, String, Tree, Binary Search, Trie
2. 알고리즘 설계
- Trie 문제이다.
insert
함수- 배열에 글자를 저장하기 때문에 배열의 칸을 1칸씩 늘리면서 저장하게 된다.
- 마치 자료구조 heap처럼
- 만약 현재 삽입중인 문자열을 다 기록했는데, 현재의 포인터와 배열의 크기가 같지 않다면,
- 현재 입력중인 문자열 전체가 어떤 문자열의 접두어란 뜻
- 현재 방문 위치를 기록하는
chk
배열을 통해 재방문 방지
- 배열에 글자를 저장하기 때문에 배열의 칸을 1칸씩 늘리면서 저장하게 된다.
3. 전체 코드
#include <bits/stdc++.h>
using namespace std;
const int MX = 10000 * 10 + 5; // 최대 길이가 10인 10000개 문자열 고려
const int ROOT = 1;
int unused = ROOT + 1;
int nxt[MX][10];
bool chk[MX];
int t, n;
int ctoi(char c) { return c - '0'; }
bool insert(string &s) {
int cur = ROOT;
for (auto c : s) {
if (nxt[cur][ctoi(c)] == -1)
nxt[cur][ctoi(c)] = unused++;
cur = nxt[cur][ctoi(c)];
if (chk[cur]) return 0;
}
if (cur != unused - 1) return 0;
return chk[cur] = 1;
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> t;
while (t--) {
fill(chk, chk + MX, 0);
for (int i = 0; i < MX; i++)
fill(nxt[i], nxt[i] + 10, -1);
unused = ROOT + 1;
bool isvalid = 1;
cin >> n;
string s;
while (n--)
{
cin >> s;
if (!insert(s)) isvalid = 0;
}
cout << (isvalid ? "YES" : "NO") << '\n';
}
}