Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

38-Munbin-Lee #155

Merged
merged 1 commit into from
Mar 13, 2024
Merged

38-Munbin-Lee #155

merged 1 commit into from
Mar 13, 2024

Conversation

Munbin-Lee
Copy link
Member

@Munbin-Lee Munbin-Lee commented Mar 7, 2024

πŸ”— 문제 링크

https://www.acmicpc.net/problem/5052

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1μ‹œκ°„

✨ μˆ˜λ„ μ½”λ“œ

문제 μ„€λͺ…

μ „ν™”λ²ˆν˜Έ λͺ©λ‘μ΄ 주어진닀.

이 λ•Œ, μž„μ˜μ˜ μ „ν™”λ²ˆν˜Έκ°€ λ‹€λ₯Έ μ „ν™”λ²ˆν˜Έμ˜ 접두어인 κ²½μš°κ°€ μžˆλŠ”μ§€ νŒλ³„ν•˜μž.


λ¨Όμ € 완전탐색을 ν•΄λ³΄μž.

λͺ¨λ“  μ „ν™”λ²ˆν˜Έ μŒμ„ κ΅¬ν•˜μ—¬ ν•œ μ „ν™”λ²ˆν˜Έκ°€ λ‹€λ₯Έ μ „ν™”λ²ˆν˜Έμ˜ 접두어인지 ν™•μΈν•˜λ©΄ λœλ‹€.

λ”°λΌμ„œ $_nC_2 10$ -> μ•½ 5μ–΅ 번의 연산이 ν•„μš”ν•˜λ‹€.


12, 45, 123 μ„Έ μ „ν™”λ²ˆν˜Έκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ,

이λ₯Ό μ •λ ¬ν•˜λ©΄

12, 123, 45κ°€ λœλ‹€.

즉, μ •λ ¬ν•˜λ©΄ λΉ„μŠ·ν•œ μ „ν™”λ²ˆν˜ΈλΌλ¦¬ μΈμ ‘ν•˜κ²Œ λœλ‹€!

λ”°λΌμ„œ 정렬을 μ œμ™Έν•œ μ‹œκ°„λ³΅μž‘λ„κ°€ $O(N)$으둜 μ€„μ–΄λ“œλ―€λ‘œ μ‹œκ°„ 내에 ν•΄κ²°ν•  수 μžˆλ‹€.

λ‚˜λŠ” 이 방법을 λ– μ˜¬λ¦¬μ§€ λͺ»ν•˜κ³  λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ ν’€μ—ˆλŠ”λ°,

문제 νƒœκ·Έμ— 정렬이 μ™œ μžˆλŠ”μ§€ κΆκΈˆν•΄μ„œ λ‚œμ΄λ„ κΈ°μ—¬ 내역을 보고 λ– μ˜¬λ Έλ‹€.

image


λ‚΄κ°€ 이 문제λ₯Ό ν•΄κ²°ν•œ 방법은 트라이(Trie)λ₯Ό μ‚¬μš©ν•˜λŠ” 것이닀.

image

νŠΈλΌμ΄λŠ” λ¬Έμžμ—΄ 집합을 κ΄€λ¦¬ν•˜λŠ” νŠΈλ¦¬λ‹€. 루트 λ…Έλ“œμ—μ„œ 리프 λ…Έλ“œκΉŒμ§€ μ—°κ²°λœ 간선을 λͺ¨λ‘ 이으면 단어가 μ™„μ„±λœλ‹€.

TλŠ” Terminal, λμ΄λΌλŠ” λœ»μ΄λ‹€.

μ „ν™”λ²ˆν˜Έλ“€μ„ νŠΈλΌμ΄μ— μ €μž₯ν•˜λ©΄μ„œ 각 μ „ν™”λ²ˆν˜Έκ°€ μž„μ˜μ˜ μ „ν™”λ²ˆν˜Έμ˜ 접두어인지 μ²΄ν¬ν•˜λ©΄ λœλ‹€.


그럼 μ–΄λ–»κ²Œ μ²΄ν¬ν•˜λ©΄ 될까?

접두어인 μ „ν™”λ²ˆν˜Έκ°€ λ¨Όμ € μž…λ ₯λ˜λŠ” κ²½μš°μ™€ 접두어인 μ „ν™”λ²ˆν˜Έκ°€ λ‚˜μ€‘μ— μž…λ ₯λ˜λŠ” 경우

2가지 μΌ€μ΄μŠ€λ‘œ λ‚˜λˆ„μ–΄ μƒκ°ν•΄λ³΄μž.


접두어인 μ „ν™”λ²ˆν˜Έκ°€ λ¨Όμ € μž…λ ₯λ˜λŠ” 경우

ex. 911, 9112

λ¨Όμ € 911을 νŠΈλΌμ΄μ— μ €μž₯ν•˜λ©΄

image

μ΄λ ‡κ²Œ λœλ‹€.

κ·Έ ν›„, 9112λ₯Ό μ €μž₯ν•  λ•Œ, 911 κΉŒμ§€ μ €μž₯ν–ˆμ„ λ•Œ Terminal을 κ±°μΉ˜λ―€λ‘œ 이 λ•Œ μ ‘λ‘μ–΄μž„μ„ 확인할 수 μžˆλ‹€.

즉, 문자λ₯Ό μ•žμ—μ„œλΆ€ν„° ν•˜λ‚˜μ”© μ €μž₯ν•˜λ©΄μ„œ Terminal을 κ±°μ³€λŠ”μ§€ ν™•μΈν•˜λ©΄ λœλ‹€.


접두어인 μ „ν™”λ²ˆν˜Έκ°€ λ‚˜μ€‘μ— μž…λ ₯λ˜λŠ” 경우

ex. 9112, 911

λ¨Όμ € 9112λ₯Ό νŠΈλΌμ΄μ— μ €μž₯ν•˜λ©΄

image

μ΄λ ‡κ²Œ λœλ‹€.

그리고 911을 νŠΈλΌμ΄μ— μ €μž₯ν•˜λ©΄

image

μ΄λ ‡κ²Œ λœλ‹€.

첫번째 μΌ€μ΄μŠ€μ™€ 달리 μ €μž₯ 쀑 Terminal을 κ±°μΉ˜μ§€ μ•Šμ•˜λ‹€.

그런데, 911μ—μ„œ Terminal이 λ˜μ—ˆλŠ”λ°λ„ λΆˆκ΅¬ν•˜κ³  911의 μžμ‹ 2(9112)κ°€ μ‘΄μž¬ν•œλ‹€.

λ”°λΌμ„œ μ €μž₯ μ’…λ£Œ ν›„ Terminal λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œκ°€ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•˜λ©΄ λœλ‹€.

πŸ“š 전체 μ½”λ“œ

#include <iostream>
#include <vector>

using namespace std;

struct Trie {
    struct Node {
        Node *children[10]{};
        bool isTerminal = false;
    };

    Node *root = new Node;

    bool insert(string &s) const {
        auto cur = root;

        for (char ch: s) {
            int digit = ch - '0';

            if (!cur->children[digit]) {
                cur->children[digit] = new Node();
                cur = cur->children[digit];
                continue;
            }

            if (cur->children[digit]->isTerminal) {
                return false;
            }

            cur = cur->children[digit];
        }

        for (auto child: cur->children) {
            if (child) {
                return false;
            }
        }

        cur->isTerminal = true;

        return true;
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    auto solve = []() {
        auto trie = new Trie;

        int n;
        cin >> n;

        vector<string> numbers(n);

        for (auto &number: numbers) {
            cin >> number;
        }

        for (auto number: numbers) {
            if (!trie->insert(number)) {
                cout << "NO\n";
                delete trie;
                return;
            }
        }

        cout << "YES\n";
    };

    int t;
    cin >> t;

    while (t--) {
        solve();
    }

    return 0;
}

@9kyo-hwang
Copy link

μ„ μƒλ‹˜ 트라이 썼을 λ•Œ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄λž‘ 톡과 μ‹œκ°„ μ–΄μΌ€ λ‚˜μ˜€μ…¨λ‚˜μš”

@Munbin-Lee
Copy link
Member Author

μ„ μƒλ‹˜ 트라이 썼을 λ•Œ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄λž‘ 톡과 μ‹œκ°„ μ–΄μΌ€ λ‚˜μ˜€μ…¨λ‚˜μš”

image

Copy link
Member

@tgyuuAn tgyuuAn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ™€μš° 트라이 λŒ€λ°• 처음 μ•Œμ•˜λ„€μš” γ…Žγ„·γ„·γ„·

λ‹€μŒ PR에 트라이 문제 ν•œλ²ˆ ν’€μ–΄λ³΄κ² μ”λ‹ˆλ‹€

μ €λŠ” ν•œλ²ˆ λ©”λͺ¨μž₯에 λ„μ μ—¬λ΄€λŠ”λ° μ •λ ¬ν•˜λ©΄ κ·Έ μ•žμ—κ±°λ§Œ νƒμƒ‰ν•˜λ©΄ 될 것 κ°™μ•„μ„œ κ·Έλƒ₯ 무심코 툭 λ˜μ Έλ΄€λŠ”λ° μ§„μ§œ ν’€λ¦¬λ„€μš” (μŠ› ν–ˆμ„ λ•Œ 사싀 100% μž₯담을 λͺ»ν–ˆμŒ)

import sys

def input(): return sys.stdin.readline().rstrip()

T = int(sys.stdin.readline())


for _ in range(T):
    N = int(input())
    
    phone_book = sorted([input() for _ in range(N)])
    is_consistency = True
    
    prev = phone_book[0]
    for number in phone_book[1:]:
        if number[:len(prev)] == prev:
            is_consistency = False
            break
        
        prev = number

    print("YES" if is_consistency else "NO")

ν’€λ¦¬λ‹ˆκΉŒ 기뢄은 쒋은데 100% λ§žμ·„λ‹€κ³  μž₯담을 λͺ»ν•œ μƒνƒœλ‘œ κ·Έλƒ₯ 던져본거라 쑰금 μ»Ήsν•˜λ„€μš” . ν—ˆν—ˆ

트라이 ν‚€μ›Œλ“œ κ°–κ³  κ°‘λ‹ˆλ‹€.

Copy link
Collaborator

@H0ngJu H0ngJu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TrieλΌλŠ” μžλ£Œκ΅¬μ‘°λ„ μžˆκ΅°μš” 덕뢄에 자료ꡬ쑰 ν•˜λ‚˜ 더 μ•Œμ•„κ°‘λ‹ˆλ‹€ !! πŸ‘πŸ‘Trieλ₯Ό μ‚¬μš©ν•˜λŠ” λ‹€λ₯Έ λ¬Έμ œλ„ κΆκΈˆν•˜λ„€μš”. λ¬Έμ œν‘ΈλŠλΌ μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€ -!

μ €λŠ” 일단 정렬을 해두고, 쌍으둜 λΉ„κ΅ν•˜λ©΄μ„œ 일관성이 μ—†μœΌλ©΄ λ°”λ‘œ λ°˜λ³΅λ¬Έμ„ λ‚˜μ˜€λ„λ‘ κ΅¬ν˜„ν•˜μ˜€μŠ΅λ‹ˆλ‹€. ν†΅κ³ΌλŠ” ν–ˆμ§€λ§Œ μ΅œμ„ μΈμ§€λŠ” 잘 λͺ¨λ₯΄κ² λ„€μš©.. 쩝

import sys

case = int(sys.stdin.readline().strip())

phoneNum = []
result = []

for _ in range(case):
    n = int(sys.stdin.readline().strip())
    phone_list = []
    for i in range(n):
        phone_list.extend(list(map(str, sys.stdin.readline().strip().split())))
    phone_list.sort()
    phoneNum.append(phone_list)

for i in range(case):
    isConsistent = True
    for s in range(len(phoneNum[i]) - 1):
        if phoneNum[i][s] == phoneNum[i][s + 1][:len(phoneNum[i][s])]:
            isConsistent = False
            break
    
    if isConsistent:
        result.append("YES")
    else:
        result.append("NO")
        
for res in result:
    print(res)

@pknujsp
Copy link
Collaborator

pknujsp commented Mar 12, 2024

(https://school.programmers.co.kr/learn/courses/30/lessons/17685) 전에 이 문제 ν’€λ©΄μ„œ μ•Œκ²Œλœ 자료ꡬ쑰인데
이 문제 ν’€μ—ˆλ˜ 기얡을 천천히 λ”λ“¬μ–΄λ³΄λ©΄μ„œ ν•˜λ‹ˆ ν’€λ¦¬λ„€μš”

μž…λ ₯ λ¬Έμžμ—΄μ˜ λͺ¨λ“  문자λ₯Ό λ…Έλ“œλ‘œ ν•˜λŠ” 트리λ₯Ό λ§Œλ“  ν›„, λ‹€μ‹œ λͺ¨λ“  λ¬Έμžμ—΄μ— λŒ€ν•΄μ„œ 트리 탐색을 ν•˜λŠ”λ°

쀑간에 ν•΄λ‹Ή λ¬Έμžμ—΄μ˜ λ§ˆμ§€λ§‰ 문자인 λ…Έλ“œκ°€ λ¦¬ν”„λ…Έλ“œκ°€ μ•„λ‹ˆλΌλ©΄ 일관성이 μ—†λŠ” κ±°λ‹ˆ NOλ₯Ό 좜λ ₯ν•˜κ³ 
λ‹€μŒ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ‘œ λ„˜μ–΄κ°‘λ‹ˆλ‹€.
λͺ¨λ“  λ¬Έμžμ—΄μ˜ λ§ˆμ§€λ§‰ λ¬Έμžκ°€ λ¦¬ν”„λ…Έλ“œλΌλ©΄ μ–΄λ– ν•œ 번호λ₯Ό λˆ„λ₯΄λ”라도 쀑간에 μ€‘λ³΅λ˜λŠ” λ²ˆν˜Έκ°€ μ—†μœΌλ―€λ‘œ YESλ₯Ό 좜λ ₯ν•΄μš”

from sys import *

for _ in range(int(stdin.readline())):
    n = int(stdin.readline())
    nums = [stdin.readline().strip() for _ in range(n)]
    tree = {}
    
    for x in nums:
        node = tree
        for c in x:
            if c not in node:
                node[c] = {'leaf': True}
            else:
                node[c]['leaf'] = False
                
            node = node[c]
    
    is_valid = True
    for x in nums:
        node = tree
        for i in range(len(x)):
            node = node[x[i]]
            
            if i == len(x) - 1 and len(node.values()) > 1:
                is_valid = False
                break
                
        if not is_valid:
            break

    print('YES' if is_valid else 'NO')

@tgyuuAn tgyuuAn mentioned this pull request Mar 13, 2024
@Munbin-Lee Munbin-Lee merged commit 44fc5a3 into main Mar 13, 2024
1 check passed
@Munbin-Lee Munbin-Lee deleted the 38-Munbin-Lee branch March 13, 2024 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants