DevYoon

[λ°±μ€€] 1043. 거짓말 (Python) λ³Έλ¬Έ

PS/Baekjoon

[λ°±μ€€] 1043. 거짓말 (Python)

gimewn 2022. 9. 14. 18:58

link πŸ”— https://www.acmicpc.net/problem/1043

 

1043번: 거짓말

μ§€λ―Όμ΄λŠ” νŒŒν‹°μ— κ°€μ„œ 이야기 ν•˜λŠ” 것을 μ’‹μ•„ν•œλ‹€. νŒŒν‹°μ— 갈 λ•Œλ§ˆλ‹€, μ§€λ―Όμ΄λŠ” 지민이가 κ°€μž₯ μ’‹μ•„ν•˜λŠ” 이야기λ₯Ό ν•œλ‹€. μ§€λ―Όμ΄λŠ” κ·Έ 이야기λ₯Ό 말할 λ•Œ, μžˆλŠ” κ·ΈλŒ€λ‘œ μ§„μ‹€λ‘œ λ§ν•˜κ±°λ‚˜ μ—„μ²­λ‚˜κ²Œ

www.acmicpc.net

❗ μ£Όλͺ©ν•œ 점

✏️ 진싀을 μ•Œκ²Œ 된 μ‚¬λžŒκ³Ό 같은 νŒŒν‹°μ— κ°€λ©΄ 진싀을 μ•Œκ²Œ λœλ‹€

✏️ 1이 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒμ΄κ³ , 1κ³Ό 4κ°€ 같은 νŒŒν‹°μ— κ°„ 경우, 4κ°€ μ°Έμ—¬ν•œ λͺ¨λ“  νŒŒν‹°κ°€ 거짓말을 ν•  수 μ—†λŠ” νŒŒν‹°κ°€ λœλ‹€.

 

1️⃣ 3% λŒ€μ—μ„œ μ˜€λ‹΅λ‚œ μ½”λ“œ

import sys
input = sys.stdin.readline

def knowTruth(y):
    for idx in range(1, len(party[y])):
        check[party[y][idx]] = 1 # 진싀을 μ•Œκ³  μžˆμœΌλ―€λ‘œ 체크

N, M = map(int, input().split()) # μ‚¬λžŒμ˜ 수, νŒŒν‹°μ˜ 수
truth = list(map(int, input().split())) # 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒμ˜ 수 + 번호
truthNum = truth.pop(0) # 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒμ˜ 수
check = [0] * (N+1) # 진싀을 μ•Œκ³  μžˆλŠ”μ§€ 체크
party = [0]*M # νŒŒν‹°
res = 0

for t in truth: # 졜초의 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒ 체크
    check[t] = 1

for idx in range(M):
    party[idx] = list(map(int, input().split()))

for y in range(M):
    for x in range(1, len(party[y])):
        if check[party[y][x]]:
            knowTruth(y) # 진싀을 μ•„λŠ” μ‚¬λžŒμ΄ μ°Έκ°€ν•œ νŒŒν‹° => μ°Έμ—¬μž λͺ¨λ‘κ°€ 진싀을 μ•Œκ²Œ 됨

for y in range(M-1, -1, -1):
    for x in range(1, len(party[y])):
        if check[party[y][x]]:
            knowTruth(y) # 진싀을 μ•„λŠ” μ‚¬λžŒμ΄ μ°Έκ°€ν•œ νŒŒν‹° => μ°Έμ—¬μž λͺ¨λ‘κ°€ 진싀을 μ•Œκ²Œ 됨


for y in range(M):
    temp = 0
    for x in range(1, len(party[y])):
        temp += check[party[y][x]] # 진싀을 μ•Œκ³  있으면 +1
    if temp == 0: # tempκ°€ 0이면 진싀을 μ•„λŠ” μ‚¬λžŒμ΄ μ—†λ‹€λŠ” 뜻
        res += 1 # 거짓말 ν•  수 μžˆλŠ” νŒŒν‹° +1

print(res)

- 쀑간에 진싀을 μ•Œκ²Œ 된 경우, ν•΄λ‹Ή μ‚¬λžŒμ΄ ν¬ν•¨λœ λͺ¨λ“  νŒŒν‹°λ₯Ό 거짓말 ν•  수 μ—†λŠ” νŒŒν‹°λ‘œ 체크해야 ν•œλ‹€.

- κ·ΈλŸ¬λ‚˜ μœ„ μ½”λ“œλ‘œλŠ” νŒŒν‹° 리슀트λ₯Ό μ•žμ—μ„œλΆ€ν„° ν•œ 번, λ’€μ—μ„œλΆ€ν„° ν•œ 번 λ”± 2번 μ²΄ν¬ν•˜λ―€λ‘œ μΆ©λΆ„νžˆ λͺ¨λ“  경우λ₯Ό μ²΄ν¬ν•˜μ§€ λͺ»ν–ˆλ‹€.

 

2️⃣ ν†΅κ³Όν•œ μ½”λ“œ

import sys
input = sys.stdin.readline

N, M = map(int, input().split()) # μ‚¬λžŒμ˜ 수, νŒŒν‹°μ˜ 수
truth = list(map(int, input().split()))[1:] # 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒλ“€μ˜ 번호 리슀트
check = [0] * (N+1) # 진싀을 μ•Œκ³  μžˆλŠ”μ§€ 체크
party = [0]*M
party_check = [1]*M # 거짓말 ν•  수 μžˆλŠ” νŒŒν‹°μΈμ§€ 체크

for t in truth: # 졜초의 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒ 체크
    check[t] = 1

for idx in range(M):
    party[idx] = list(map(int, input().split()))[1:] # νŒŒν‹° μˆœμ„œλŒ€λ‘œ μž…λ ₯

while truth:
    truth_person = truth.pop()

    dontKnow = set() # 진싀을 아직 λͺ¨λ₯΄λŠ” μ‚¬λžŒλ“€

    for idx in range(M):
        if truth_person in party[idx]: # νŒŒν‹°μ— 진싀을 μ•Œκ³  μžˆλŠ” μ‚¬λžŒμ΄ 있으면
            party_check[idx] = 0 # 거짓말 ν•  수 μ—†μœΌλ―€λ‘œ 체크 ν•΄μ œ
            dontKnow = dontKnow.union(party[idx]) # 진싀을 아직 λͺ¨λ₯΄λŠ” μ‚¬λžŒλ“€μ— νŒŒν‹°μ›λ“€ μΆ”κ°€

    for person in dontKnow:
        if not check[person]: # 아직 진싀을 λͺ¨λ₯΄λ©΄
            truth.append(person) # 진싀을 μ•Œκ²Œ λ˜μ—ˆμœΌλ―€λ‘œ truth λ¦¬μŠ€νŠΈμ— μΆ”κ°€
            check[person] = 1 # 체크

print(sum(party_check))

- ꡬ글링해본 κ²°κ³Ό, 진싀을 μ•Œκ²Œ 될 λ•Œλ§ˆλ‹€ κ·Έ μ‚¬λžŒμ˜ 번호λ₯Ό truth λ¦¬μŠ€νŠΈμ— λ‹΄μ•„μ£Όμ—ˆκ³ , while문을 톡해 λͺ¨λ“  경우λ₯Ό μ²΄ν¬ν•΄μ£Όμ—ˆλ‹€.

- party_check λ¦¬μŠ€νŠΈμ— λͺ¨λ“  νŒŒν‹°λ₯Ό 거짓말할 수 μžˆλŠ” 것(1)둜 체크해두고, 거짓말 ν•  수 μ—†λ‹€κ³  λ°ν˜€μ§€λŠ” μˆœκ°„ 0으둜 값을 λ°”κΏ”μ£Όμ—ˆλ‹€.

- λ§ˆμ§€λ§‰μ— party_check 리슀트의 합을 κ΅¬ν•˜λ©΄ 거짓말할 수 μžˆλŠ” νŒŒν‹°μ˜ κ°―μˆ˜κ°€ λ‚˜μ˜¨λ‹€.