๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm/์ด๋ก 

Trie(ํŠธ๋ผ์ด) ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋ฌธ์ž์—ด ์ €์žฅ Trie(ํŠธ๋ผ์ด) ์•Œ๊ณ ๋ฆฌ์ฆ˜ C++

Trie ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋ฌธ์ž์—ด์„ ์ €์žฅํ•˜๊ณ , ํ•ด๋‹น ๋ฌธ์ž์—ด์˜ ์ €์žฅ ์œ ๋ฌด๋ฅผ ํ™•์ธํ•  ๋•Œ ์“ฐ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

์˜ˆ์‹œ

"vivid" ๋ผ๋Š” ๋ฌธ์ž์—ด์„ ์ €์žฅํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค.

๊ฐ€์žฅ ๋งจ ์œ„์— ์ž๋ฃŒ๋ฅผ ์ €์žฅํ•  ๋ฃจํŠธ ๋…ธ๋“œ๊ฐ€ ์žˆ์„ ๊ฒƒ์ด๊ณ , ๊ทธ ๋ฃจํŠธ ๋…ธ๋“œ ์•„๋ž˜ v๋ฅผ ์ €์žฅ,

v๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๋…ธ๋“œ ์•„๋ž˜ i๊ฐ€ ์ €์žฅ

i๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๋…ธ๋“œ ์•„๋ž˜ v๋ฅผ ์ €์žฅ.. ์ด๋Ÿฐ ์‹์œผ๋กœ ๋งˆ์ง€๋ง‰ d๊นŒ์ง€ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

 

 

์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์—ด์ธ vivid์˜ d ๋’ค์—” ๋ฌธ์ž์—ด์˜ ๋์„ ์•Œ๋ฆฌ๋Š” '\0'์ด ๋ถ™์–ด์žˆ์„ ๊ฒƒ์ด๋ฏ€๋กœ, ์ด๋ฅผ d ๋…ธ๋“œ์— ํ‘œ์‹œ(๋…ธ๋ž€์ƒ‰ ๋…ธ๋“œ)๋ฅผ ํ•ด์ค์‹œ๋‹ค.

์ด๋Ÿฐ ์‹์œผ๋กœ ๋ฃจํŠธ ๋…ธ๋“œ ์•„๋ž˜ ์ €์žฅํ•  ๋‹จ์–ด๋“ค์˜ ๋…ธ๋“œ๋ฅผ ํ™•์žฅ ์‹œํ‚ต๋‹ˆ๋‹ค.

"vivid" ์™ธ์— "sw", "swan", "sweet"๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

์‹œ๊ฐ„, ๊ณต๊ฐ„ ๋ณต์žก๋„

ํŠธ๋ผ์ด๋Š” ๊ฐ ๋ฌธ์ž๋งˆ๋‹ค ์ธ๋ฑ์‹ฑ์„ ํ•ด์„œ ์ž๋ฃŒ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ํƒ์ƒ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ฐพ๋Š” ๋ฌธ์ž์—ด์˜ ๋ฌธ์ž ์ˆ˜๊ฐ€ N ๊ฐœ๋ผ๋ฉด N ๋ฒˆ๋งŒ์— ํŠน์ • ๋ฌธ์ž์—ด์˜ ์œ ๋ฌด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ์ธ๋ฑ์‹ฑ์„ ํ•˜๋ฉด์„œ ๋ฌธ์ž๋ฅผ ์‚ฝ์ž…ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ตœ์•…์˜ ๊ฒฝ์šฐ์— ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž ์ˆ˜๊ฐ€ M ๊ฐœ๋ผ๊ณ  ํ•œ๋‹ค๋ฉด N ๊ฐœ๊นŒ์ง€์˜ ์ œํ•œ์ด ์žˆ๋Š” ๋ฌธ์ž์—ด์—์„  ์ตœ์•…์˜ ๊ฒฝ์šฐ M^N์˜ ๊ณต๊ฐ„ ๋ณต์žก๋„๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค ๋ณด๋‹ค ๋งŽ์€ ๊ณต๊ฐ„ ๋ณต์žก๋„๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

 

๊ตฌํ˜„

CPP์—์„  Trie๋ฅผ ๋ณดํ†ต ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์กฐ์ฒด์— ๋‹ค์Œ ์ธ๋ฑ์‹ฑ ๋…ธ๋“œ์˜ ํฌ์ธํ„ฐ ๋ฐฐ์—ด๋“ค์„ ๋ชจ๋‘ nullptr๋กœ ์„ ์–ธํ•œ ๋’ค, ํ•ด๋‹น ๊ณต๊ฐ„์ด ํ•„์š”ํ•  ๋•Œ ์ƒˆ๋กœ์šด ๊ตฌ์กฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

๊ฐ ๋…ธ๋“œ์—๋Š” ํ•„์š”ํ•œ ๊ฐ’๋“ค์„ ์ €์žฅํ•ด ์ค€๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„ ๊ทธ๋ฆผ์˜ ๋‹ค์Œ ๋ฌธ์ž๊ฐ€ '\0'์ธ ๊ฒฝ์šฐ๋„ boolํ˜•์œผ๋กœ ์ฒดํฌํ•ด ์ฃผ๊ณ  ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‹ค ์“ด Trie๋Š” ๋™์  ํ• ๋‹น ํ•ด์ œ๋ฅผ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Trie์˜ ๋Œ€ํ‘œ ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ด…์‹œ๋‹ค.


๋ฌธ์ œ : BOJ_5052๋ฒˆ ์ „ํ™”๋ฒˆํ˜ธ ๋ชฉ๋ก

๋ฌธ์ œ๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ์ฝ์–ด๋ณด๋ฉด, ์ผ๊ด€์„ฑ์„ ํŒ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด์„  ๊ฒฐ๊ตญ ๋‹ค์Œ ๋ฌธ์ž๊ฐ€ '\0' ์ธ ๊ฒฝ์šฐ๋กœ ์ฒดํฌ๋˜์—ˆ๋Š”๋ฐ, ๋‹ค๋ฅธ ๋ฌธ์ž๋„ ์ž์‹ ๋…ธ๋“œ๋กœ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉด ์ผ๊ด€์„ฑ์— ์–ด๊ธ‹๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์†Œ์Šค์ž…๋‹ˆ๋‹ค.

#include <iostream>
#include <cstring>
using namespace std;
bool isConsistent = true;
struct Trie {
    bool isWord;
    bool existChild;
    Trie* childTrie[10];
    Trie() {
        isWord = false;
        existChild = false;
        for (int i = 0; i < 10; i++) childTrie[i] = nullptr;
    }
    ~Trie() {
        for (int i = 0; i < 10; i++) {
            if (childTrie[i]) delete childTrie[i];
        }
    }

    void insert(char* word) {
        if (*word == '\0') isWord = true;
        else {
            int next = *word - '0';
            if (!childTrie[next]) childTrie[next] = new Trie;
            existChild = true;
            childTrie[next]->insert(word + 1);
        }
        if (isWord && existChild) isConsistent = false;
    }
};
int main(void) {
    int T;
    cin >> T;
    for (int i = 0; i < T; i++) {
        isConsistent = true;
        Trie* trie = new Trie;
        int N;
        cin >> N;
        for (int j = 0; j < N; j++) {
            char word[11];
            cin >> word;
            trie->insert(word);
        }
        if (isConsistent) cout << "YES\n";
        else cout << "NO\n";
        delete trie;
    }
}

์ฐจ๊ทผ์ฐจ๊ทผ ์†Œ์Šค๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด,

struct Trie {
    bool isWord;
    bool existChild;
    Trie* childTrie[10];
    Trie() {
        isWord = false;
        existChild = false;
        for (int i = 0; i < 10; i++) childTrie[i] = nullptr;
    }
    ~Trie() {
        for (int i = 0; i < 10; i++) {
            if (childTrie[i]) delete childTrie[i];
        }
    }
}

๋๋‚˜๋Š” ๋ฌธ์ž์—ด์ธ๊ฐ€์˜ ์œ ๋ฌด์ธ isWord, ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ–ˆ๋Š”์ง€ ์œ ๋ฌด์ธ existChild, ์ž์‹ ๋…ธ๋“œ์˜ ํฌ์ธํ„ฐ ๋ฐฐ์—ด์„ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์„ฑํ•  ๋•Œ for (int i = 0; i < 10; i++) childTrie[i] = nullptr; ๋กœ ํฌ์ธํ„ฐ ๋ฐฐ์—ด์„ ๋ชจ๋‘ null๋กœ ์„ธํŒ…ํ•ฉ๋‹ˆ๋‹ค.

    void insert(char* word) {
        if (*word == '\0') isWord = true;
        else {
            int next = *word - '0';
            if (!childTrie[next]) childTrie[next] = new Trie;
            existChild = true;
            childTrie[next]->insert(word + 1);
        }
        if (isWord && existChild) isConsistent = false;
    }

์‚ฝ์ž…ํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ์‚ฝ์ž…ํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ž์—ด์ด '\0'์ด๋ผ๋ฉด, isWord๋ฅผ true๋กœ ํ•ด์ฃผ๊ณ  ์ข…๋ฃŒ,

'\0'์ด ์•„๋‹ˆ๋ผ๋ฉด ์ธ๋ฑ์‹ฑ์— ๋งž๊ฒŒ ๋‹ค์Œ ๋ฌธ์ž๋ฅผ ์‚ฝ์ž…ํ•ด ์ค๋‹ˆ๋‹ค.

์ด๋•Œ ์ธ๋ฑ์‹ฑ์— ๋งž๋Š” ํฌ์ธํ„ฐ ๋ฐฐ์—ด์ด null์ด๋ผ๋ฉด Trie ๋…ธ๋“œ๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ๊ณ , ์ž์‹ ๋…ธ๋“œ์˜ ์œ ๋ฌด์ธ existChild๋„ true๋กœ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค.


๋งˆ์ง€๋ง‰ ์ค„์˜ if (isWord && existChild) isConsistent = false;๋Š” ์ผ๊ด€์„ฑ์„ ํŒ๋‹จํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

์ž๋ฐ”๋กœ๋„ Trie๋ฅผ ์งค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž๋ฐ”๋Š” ํฌ์ธํ„ฐ ๋ฐฐ์—ด์ด ํ•„์š” ์—†์ด new๋กœ ํž™ ์˜์—ญ์— ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ๋™์  ํ• ๋‹น ํ•ด์ œ๋ฅผ ํ•ด์ค€๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” ๋˜‘๊ฐ™์€ ๋…ผ๋ฆฌ๋กœ ์œ„์˜ ๋ฌธ์ œ๋ฅผ ์ž๋ฐ”๋กœ ํ’€์ดํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Java_5052_์ „ํ™”๋ฒˆํ˜ธ๋ชฉ๋ก {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        for(int i=0;i<T;i++) {
            int n = Integer.parseInt(br.readLine());
            Trie trie = new Trie();
            for(int j=0;j<n;j++) {
                String word = br.readLine();
                trie.insert(word);
            }
            if(Trie.isConsistency) System.out.println("YES");
            else System.out.println("NO");
            Trie.isConsistency=true;
        }
    }

}

class Trie {
    static boolean isConsistency=true;
    // ์ •์  ๋ณ€์ˆ˜
    boolean isWord = false;
    boolean existChild = false;
    // ๋””ํดํŠธ ์†์„ฑ
    Trie[] childTrie = new Trie[10];
    void insert(String word) {
        int len = word.length();
        Trie nowTrie = this;
        for(int i=0;i<len;i++) {
            int nextNum = word.charAt(i)-'0';
            if(nowTrie.childTrie[nextNum]==null) nowTrie.childTrie[nextNum] = new Trie();
            nowTrie = nowTrie.childTrie[nextNum];
            // ์ž์‹ ๊ทธ๋ž˜ํ”„๋กœ ์ด๋™
            if(i==len-1) nowTrie.isWord=true;
            else nowTrie.existChild=true;
            if(nowTrie.isWord && nowTrie.existChild) isConsistency = false;
        }
    }
}