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

문제를 효율적이고 간결하게 해결하기 위해 집합(Set) 자료구조를 활용한 그리디 알고리즘(Greedy Algorithm) 접근 방식을 사용하겠습니다. 이 접근 방식은 각 만남 기록을 순차적으로 처리하면서, 무지개 댄스를 추는 사람의 집합을 업데이트하여 최종적으로 무지개 댄스를 추는 사람의 수를 계산합니다.
N개의 만남 기록을 순서대로 처리하여, 마지막 기록 이후 무지개 댄스를 추는 사람의 수를 구하는 것입니다.ChongChong만 무지개 댄스를 추고 있습니다.N (1 ≤ N ≤ 1,000)N줄: 각 줄에 두 사람의 이름 A_i와 B_i가 공백으로 구분되어 주어집니다.20의 문자열이며, 서로 다릅니다.ChongChong은 반드시 한 번 이상 등장합니다.예제 입력 1:
12
bnb2011 chansol
chansol chogahui05
chogahui05 jthis
jthis ChongChong
jthis jyheo98
jyheo98 lms0806
lms0806 pichulia
pichulia pjshwa
pjshwa r4pidstart
r4pidstart swoon
swoon tony9402
tony9402 bnb2011
예제 출력 1:
10
해석:
ChongChong만 무지개 댄스를 추고 있음.이 문제는 그리디 알고리즘(Greedy Algorithm)과 집합(Set) 자료구조를 사용하여 해결할 수 있습니다. 그리디 알고리즘은 매 순간 최적의 선택을 하여 전체 문제를 해결하는 방법으로, 여기서는 가능한 빨리 무지개 댄스를 추는 사람의 수를 확장해 나갑니다.
dancers 집합을 초기화합니다.ChongChong만 무지개 댄스를 추고 있으므로, dancers = {"ChongChong"}으로 설정합니다.A와 B가 만났을 때, 만난 두 사람 중 적어도 한 명이 dancers 집합에 속해 있으면, 두 사람 모두 dancers 집합에 추가합니다.dancers 집합의 크기를 출력합니다.in 연산이 평균적으로 O(1)의 시간 복잡도를 가집니다.dancers 집합에 저장하고, 새로운 사람이 추가될 때 중복 없이 관리할 수 있습니다.아래는 위의 접근 방식을 구현한 파이썬 코드입니다:
def count_dancers(N, meetings):
# 초기 상태: ChongChong만 무지개 댄스를 추고 있음
dancers = set(["ChongChong"])
for A, B in meetings:
# 만남 중 적어도 한 명이 무지개 댄스를 추고 있으면, 두 사람 모두 추가
if A in dancers or B in dancers:
dancers.add(A)
dancers.add(B)
return len(dancers)
def main():
import sys
input = sys.stdin.readline
N = int(input())
meetings = []
for _ in range(N):
parts = input().strip().split()
if len(parts) < 2:
# 만약 한 줄에 두 이름이 모두 주어지지 않았다면, 추가로 입력 받기
parts += input().strip().split()
A, B = parts
meetings.append((A, B))
result = count_dancers(N, meetings)
print(result)
if __name__ == "__main__":
main()
count_dancers(N, meetings)N: 만남 기록의 수meetings: 만남 기록 리스트. 각 요소는 두 사람의 이름을 튜플로 저장한 형태입니다.int)dancers: 무지개 댄스를 추는 사람들의 집합. 초기에는 {"ChongChong"}으로 시작합니다.for A, B in meetings:
if A in dancers or B in dancers:
dancers.add(A)
dancers.add(B)
(A, B)을 순서대로 처리합니다.dancers 집합에 속해 있으면, 두 사람 모두 dancers 집합에 추가합니다.return len(dancers)
dancers 집합의 크기를 반환합니다.def main():
import sys
input = sys.stdin.readline
N = int(input())
meetings = []
for _ in range(N):
parts = input().strip().split()
if len(parts) < 2:
# 만약 한 줄에 두 이름이 모두 주어지지 않았다면, 추가로 입력 받기
parts += input().strip().split()
A, B = parts
meetings.append((A, B))
result = count_dancers(N, meetings)
print(result)
N을 입력받습니다.N개의 줄에서 두 사람의 이름 A와 B를 입력받아 meetings 리스트에 저장합니다.A와 B를 완성합니다.count_dancers 함수를 호출하여 최종 결과를 계산합니다.예제 입력 1:
12
bnb2011 chansol
chansol chogahui05
chogahui05 jthis
jthis ChongChong
jthis jyheo98
jyheo98 lms0806
lms0806 pichulia
pichulia pjshwa
pjshwa r4pidstart
r4pidstart swoon
swoon tony9402
tony9402 bnb2011
처리 과정:
dancers = {"ChongChong"}bnb2011 meets chansol → 둘 다 무지개 댄스를 추지 않음 → 변화 없음chansol meets chogahui05 → 둘 다 무지개 댄스를 추지 않음 → 변화 없음chogahui05 meets jthis → 둘 다 무지개 댄스를 추지 않음 → 변화 없음jthis meets ChongChong → ChongChong이 무지개 댄스를 추고 있으므로, jthis도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis"}jthis meets jyheo98 → jthis가 무지개 댄스를 추고 있으므로, jyheo98도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98"}jyheo98 meets lms0806 → jyheo98가 무지개 댄스를 추고 있으므로, lms0806도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806"}lms0806 meets pichulia → lms0806가 무지개 댄스를 추고 있으므로, pichulia도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806", "pichulia"}pichulia meets pjshwa → pichulia가 무지개 댄스를 추고 있으므로, pjshwa도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806", "pichulia", "pjshwa"}pjshwa meets r4pidstart → pjshwa가 무지개 댄스를 추고 있으므로, r4pidstart도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806", "pichulia", "pjshwa", "r4pidstart"}r4pidstart meets swoon → r4pidstart가 무지개 댄스를 추고 있으므로, swoon도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806", "pichulia", "pjshwa", "r4pidstart", "swoon"}swoon meets tony9402 → swoon이 무지개 댄스를 추고 있으므로, tony9402도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806", "pichulia", "pjshwa", "r4pidstart", "swoon", "tony9402"}tony9402 meets bnb2011 → tony9402가 무지개 댄스를 추고 있으므로, bnb2011도 무지개 댄스를 추게 됨 → dancers = {"ChongChong", "jthis", "jyheo98", "lms0806", "pichulia", "pjshwa", "r4pidstart", "swoon", "tony9402", "bnb2011"}최종 결과: 10명이 무지개 댄스를 추고 있음.
출력:
10
집합 초기화:
dancers = set(["ChongChong"])O(1)만남 기록 순회:
for A, B in meetings:
if A in dancers or B in dancers:
dancers.add(A)
dancers.add(B)
N (1 ≤ N ≤ 1,000)A in dancers와 B in dancers: 평균적으로 O(1)의 시간 복잡도를 가집니다.dancers.add(A)와 dancers.add(B): 평균적으로 O(1)의 시간 복잡도를 가집니다.O(N)최종 결과 계산:
len(dancers)O(1)총 시간 복잡도: O(N)
N이 최대 1,000이므로, 매우 효율적으로 동작합니다.dancers):2*N개의 고유한 사람이 있을 수 있으므로, 공간 복잡도는 O(N)입니다.N이 최대 1,000이므로, 공간 사용량은 매우 작습니다.meetings):N개의 튜플을 저장하므로, 공간 복잡도는 O(N)입니다.총 공간 복잡도: O(N)
in 연산을 통해 특정 사람이 무지개 댄스를 추고 있는지 빠르게 확인할 수 있습니다.O(1) 시간 내에 원소의 존재 여부를 확인할 수 있습니다.제공된 파이썬 코드는 그리디 알고리즘과 집합(Set) 자료구조를 활용하여, 주어진 만남 기록을 효율적으로 처리함으로써 최종적으로 무지개 댄스를 추는 사람의 수를 정확하게 계산합니다. 시간 복잡도는 O(N), 공간 복잡도는 O(N)으로, 주어진 문제의 제한 사항 (N ≤ 1,000) 내에서 매우 효율적으로 동작합니다.
O(N)O(N)이 접근 방식은 문제의 요구사항을 정확하게 만족시키며, 코드가 간결하고 이해하기 쉬워서 코딩 테스트 환경에서도 효과적으로 사용할 수 있습니다.
set.add(element)element in setset.remove(element) 또는 set.discard(element)set1 | set2set1 & set2