1. ๋ฌธ์ ์ค๋ช ๐
(1) ๋งํฌ๐
(2) ํด์ค๐ต
๋ฌธ์ ์ค๋ช ์ด ๊ผฌ์ ์์ด ์ง๊ด์ ์ด๋ผ ๋ฐ๋ก ์ค๋ช ํ ๊ฒ์ด ์๋ค.
2. ์๊ฐ์ ํ๋ฆ: ์ฝ๋๊ฐ ๋์ค๊ธฐ๊น์ง ๐๏ธ
(0) ์์ ํ์
์ ์ ๋๋ก ๋ ํ์ด๊ฐ ์๋๋ค.
๋ง์ฝ ๋ฌธ์์ด ์ค 2๊ฐ๋ฅผ ๊ณจ๋ผ, ์์์๋ถํฐ ๋จ์ด๊ฐ ๋ช ๊ฐ๋ ๊ฐ์์ง๋ฅผ ์ ๋ถ ํ์ธ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํ์๋ค๋ฉด, SOLVED๋ ๋๊ฒ ์ง๋ง ๋ต์ด ์๋๋ค. ์๋ํ๋ฉด, ๋จ์ด์ ๊ฐ์๋ ์ต๋ 20,000 ์ด๊ณ , ๋จ์ด์ ๊ธธ์ด๋ ์ต๋ 100 ์ด๋ค. ๋ฐ๋ผ์ ์กฐํฉ
์ผ๋ก 2๊ฐ ๊ณจ๋ผ์ ๋์กฐ๋ก ํ์๋ค๋ฉด, ์๊ฐ ๋ณต์ก๋๋ O($ n\choose 2 $* 100) ์ฆ 200์ต์ด ๋์จ๋ค.
์ด๋ฌํ ์ํ๋ ์ ๋ต์ด ๋๋ ์ด์ ๋ ์์ง ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅ์ผ๋ก ๋ฃ๋ TC๊ฐ ์๋ ๋ชจ์์ด๋ค.
https://www.acmicpc.net/board/view/94785
์ฌ๊ธฐ์ ๋์ค๋ TC๊ฐ ๋์๊ฐ์ผ ํ๋ค.
(1) IDEA ๋์ถ๐ก
KEY WORD
: Tri
์ ๋์ฌ ๋ฌธ์ ๋ต๊ฒ Tri
๋ฅผ ๋จผ์ ๋ ์ฌ๋ ธ๋ค. ํ์ง๋ง ์ ํ์ ์ธ Tri๋ผ๊ธฐ ๋ณด๋จ, ๋ฌธ์ ๋ฅผ ์ํด ์กฐ๊ธ ๊ตฌ์กฐ๋ฅผ ๋ณํํด์ผ ํ๋ค.
private static class Node {
HashMap<Character,Node> children;
int word_idx;
public Node(int idx){
children = new HashMap<>();
this.word_idx = idx;
}
}
์๋ Tri์ Node๋ฅผ ๋ํ๋ด๋ Class์ด๋ค.
์ฌ๊ธฐ์ children
์ ๋ค์ ๋ฌธ์๋ฅผ ๋ํ๋ด๋ ์์ ๋
ธ๋
๋ฅผ ๋ปํ๋ค. word_idx
๋ ํด๋น ๋
ธ๋๋ฅผ ์ฒ์์ผ๋ก ํธ๋ผ์ด์ ๋ง๋ ๋ฌธ์์ด์ index๋ฅผ ๋ปํ๋ค. ์๋ฅผ ๋ค์ด ["ab", "ac"]
๋ผ๋ ์
๋ ฅ์ด ๋ค์ด์๋ค๊ณ ์ณ๋ณด์. ๊ทธ๋ ๋ค๋ฉด "ab"
์ index = 0, ac
์ index = 1์ผ ๊ฒ์ด๋ค.
๊ทธ๋ผ ์์ ๊ฐ์ ๊ตฌ์กฐ๋ก Tri์ ์ ์ฅ๋ ๊ฒ์ด๊ณ , ๊ฐ ๋
ธ๋์ word_idx
๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ด๋ค.
๋จผ์ a์ b ๋
ธ๋๊ฐ ๋ง๋ค์ด์ง๊ณ , word_idx = 0์ผ๋ก ์ด๊ธฐํ ๋์๋ค. ์ดํ ac ๋ฌธ์์ด์ด ๋ค์ด์ค๋ฉด์, depth = 1์ธ a
๋ ์ด๋ฏธ ์กด์ฌํ์ผ๋ฏ๋ก ๋์ด๊ฐ๊ณ , c๊ฐ ์๋ก ์๊ธฐ๋ฉด์ word_idx = 1์ด ๋๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ํด์ฃผ๋ ์ด์ ๋ (1) ๋ต์ด ๋ ๋๊ฐ์ง ๋ฌธ์์ด ์ค ๋๊ฐ ๋จผ์ ์ธ์ง ํ์ธ๊ณผ (2) ํ์ฌ ํ์ธ ์ค์ธ ๋ฌธ์์ด์ ์ ๋์ฌ ๊ธธ์ด์ ์ด์ ๊น์ง์ ๊ณ์ฐ ์ค ์ต๋ ์ ๋์ฌ์ ๊ธธ์ด๊ฐ ๊ฐ์ ๋, Node๊ฐ ๋ง๋ค์ด์ง ์์๋ฅผ ํ์ธํ์ฌ, ๋ต์ด ๋ ๋ฌธ์์ด์ ์ ํ๊ธฐ ์ํด์ ์ด๋ค.
๋ง์น ๋จ์ธต์ผ๋ก ์ง์งํ์ ์ฐ๋๊ธฐ๋ฅผ ์ธก์ ํ๋ ๊ฒ์ฒ๋ผ ์ฐ๋ฆฌ๋ word_idx
๋ฅผ ๋ณด๊ณ ํด๋น ๋
ธ๋๊ฐ ๋ง๋ค์ด์ง ์์ ์ ์ ์ ์๋ ๊ฒ์ด๋ค.
(2) SUDO CODE ๐
- 0๏ธโฃ ํ๋์ ๋ฌธ์์ด์ ๋ฐ์, a. ํธ๋ผ์ด์ ์ฝ์ , b. ํ ์ ๋ ฅ ๋ฌธ์์ด๊ณผ ์ ๋ ๋ฌธ์๊ฐ ์ต๋ํ ๋ง์ด ๊ฐ์ ๋ฌธ์์ด ์ฐพ๊ธฐ ๋ฅผ ๋์์ ์งํํ ๊ฒ์ด๋ค.
- 1๏ธโฃ ๋ฌธ์์ด์ ์ ๋ ฅ ๋ฐ์ tri์ insert ํจ์์ ๋ฃ๋๋ค.
- 2๏ธโฃ ๋ฌธ์์ด์ ๋ฌธ์ ํ๋๋ฅผ ํ์ธํ๋ค. (root์ ์์๋ ธ๋์ ๊ฐ์ ์ง์ด๋ฃ๋ ๊ฒ์ด ์์์ ์์ผ๋ก ์ฐ๋ฆฌ๋ ํญ์ ํ์ฌ ๋ฌธ์์ด์ ์กฐํ ์ค์ธ ๋ ธ๋์ ์์๋ ธ๋์ ์ง์ด๋ฃ๊ฒ ๋๋ค.)
- 3๏ธโฃ ํด๋น ๋ฌธ์๊ฐ ํ ๋
ธ๋์ ์์๋
ธ๋๋ก ์ด๋ฏธ ์กด์ฌํ๋์ง ํ์ธํ๋ค.
- 3-1) ์กด์ฌํ์ง ์๋๋ค๋ฉด, ์์ ๋ ธ๋์ ํ ๋ฌธ์๋ฅผ ์ง์ด๋ฃ๋๋ค.
- 3-2) ์ด๋ฏธ ์กด์ฌํ๋ค๋ฉด, ์ง๊ธ ๋์ฐฉํ ํธ๋ผ์ด์ ๊น์ด(== ์ ๋์ฌ์ ๊ธธ์ด)๊ฐ ํ์ฌ๊น์ง ๊ฐ์ฅ ๊ธธ์๋ ์ ๋์ฌ์ ๊ธธ์ด๋ณด๋ค ํฐ์ง ํ์ธํ๋ค.
- 4๏ธโฃ ํ ํธ๋ผ์ด ๊น์ด๊ฐ ๋ ํฌ๊ฑฐ๋ ๊ฐ๊ณ , ํ์ฌ ์ฝ์
์ค์ธ ๋ฌธ์์ด์ด ๊ธฐ์กด์ ๋ค์ด๊ฐ ๋ฌธ์์ด๊ณผ ๋ค๋ฅธ ๋จ์ด๋ผ๋ฉด, ๋ค์์ ์งํํ๋ค.
- 4-1)
ํ ํธ๋ผ์ด์ ๊น์ด(== ํ์ฌ ๊ณตํต ์ ๋์ฌ ๊ธธ์ด)
>ํ์ฌ๊น์ง ๊ฐ์ฅ ๊ธธ์๋ ์ ๋์ฌ ๊ธธ์ด(์ดํ MAX)
MAX ๊ฐฑ์ , ์ฒซ๋ฒ์งธ ๋ต = ๋ ธ๋์word_idx
๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฌธ์์ด (๋จผ์ ์ฝ์ ๋ ๊ฐ), ๋๋ฒ์งธ ๋ต = ํ์ฌ ์ฝ์ ์ค์ธ ๋ฌธ์์ด - 4-2)
ํ ํธ๋ผ์ด ๊น์ด
==MAX
ํ์ฌ ํ์ธ ์ค์ธ ๋ ธ๋๊ฐ ์ฒ์ ๋ง๋ค์ด์ง ์๊ธฐ๊ฐ ๋ต์ผ๋ก ์ ์ด๋ฃ์ ๋ฌธ์์ด์ด ๋ง๋ค์ด์ง ์๊ธฐ๋ณด๋ค ๋น ๋ฅด๋ค๋ฉด, ๋ต 2๊ฐ๋ฅผ4-1
์ฒ๋ผ ๊ฐฑ์ ํ๋ค.
- 4-1)
- 5๏ธโฃ ์ฝ์
์ ๋ค ๋๋ด๋ฉด, ์ด๋ฏธ ans 2๊ฐ๊ฐ ์ํ๋ ๊ฐ์ผ๋ก ์ ํ์๋ค.
(์์ธ ์ฒ๋ฆฌ - ์ด๋ค ๋ฌธ์์ด๋ ์ ๋์ฌ๊ฐ ํ๋๋ผ๋ ๊ฐ์ ๊ฒ ์๋ค๋ฉด, ๋งจ ์ฒ์, ๊ทธ ๋ค์ ์ ๋ ฅ์ ๋ต์ผ๋ก ์ ์ด ๋ธ๋ค.)
(3) ์๊ฐ๋ณต์ก๋ ๋ถ์ ๐
๋ฌธ์์ด์ ๊ฐ์: N
, ๋ฌธ์์ด์ ๊ธธ์ด: L
ํ๋ฒ์ ํธ๋ผ์ด ์์ฑ์ผ๋ก ๋ชจ๋ ๊ณ์ฐ์ด ๋๋๋ค.
: $O(NL)$
20,000 * 100 = 2,000,000 (์ฐ์ฐ ํ์: 200๋ง)
3. ๊ตฌํ ์ฝ๋ ๐
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
public class Main {
private static class Node {
HashMap<Character,Node> children;
int word_idx; // ํด๋น ๋
ธ๋๋ฅผ ๋ง๋ค์ด๋ธ ๋ฌธ์์ด์ index
public Node(int idx){
children = new HashMap<>();
this.word_idx = idx;
}
}
private static class Tri {
Node root = new Node(-1);
public void insert(String str, int word_idx) {
Node now = this.root;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(!now.children.containsKey(c)) now.children.put(c, new Node(word_idx));
else {
// ํ์ฌ ๋ค์ด์จ tri์ ๊น์ด๊ฐ ์ง๊ธ๊น์ง์ ์ต๋๊ฐ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ๋ค.
// ํ์ฌ ํ์ธํ๋ ค๋ Node(๋ค์ Node)๋ฅผ ์ ์ฅ์์ผฐ๋ ๋จ์ด๊ฐ ํ์ฌ ๋ณด๋ ๋จ์ด๋ ๊ฐ์ง ์๋ค.
if(i >= Max && !str.equals(Words[now.children.get(c).word_idx])) {
if(i > Max) {
// MAX ๊ฐฑ์
Max = i;
// ์ฒซ๋ฒ์งธ ๋ต์ ํ์ฌ ์ ๋์ฌ๊ฐ ๊ฐ์ ๊ฐ ์ค ๋จผ์ ๋ง๋ค์ด์ง ๋
์ (๋
ธ๋๋ฅผ ์ต์ด๋ก ๋ง๋ ๋ฌธ์์ด)
ans[0] = now.children.get(c).word_idx;
// ๋๋ฒ์งธ ๋ต์ ํ์ฌ ์ฝ์
์ค์ธ ๋ฌธ์์ด
ans[1] = word_idx;
} else if (i == Max) {
// ํ ๋
ธ๋๋ฅผ ๋ง๋ ๋ฌธ์์ด์ ์ฝ์
์์ ์ด ๋ต์ผ๋ก ์ ํ์๋ ๋ฌธ์์ด์ ์ฝ์
์์ ๋ณด๋ค ๋น ๋ฅด๋ฉด ๋ต์ ๊ฐฑ์ ํ๋ค.
if(now.children.get(c).word_idx < ans[0]) {
ans[0] = now.children.get(c).word_idx;
ans[1] = word_idx;
}
}
}
}
now = now.children.get(c);
}
}
}
private static int [] ans = new int [2];
private static String [] Words;
private static int Max = -1;
private static int N;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
Words = new String[N];
Tri tri = new Tri();
for (int i = 0; i < N; i++) {
Words[i] = br.readLine();
tri.insert(Words[i], i);
}
if(Max == -1) {
ans[0] = 0;
ans[1] = 1;
}
System.out.println(Words[ans[0]]);
System.out.println(Words[ans[1]]);
}
}
4. ๋ฐฐ์ด ๊ฒ๋ค ๐ฏ
์์ง ํธ๋ผ์ด์ ์์ฉ์ ์ฝํ ๋ฏ ํ๋ค. ์๊ฐ์ด ๋๋ฉด ๊ด๋ จ ๋ฌธ์ ๋ฅผ ๋ ํ์ด๋ด์ผ๊ฒ ๋ค.