기록하는삶
[코딩 테스트 연습(파이썬/Python)] 백준 16566번 _ 카드 게임 본문
https://www.acmicpc.net/problem/16566
[문제]
철수와 민수는 카드 게임을 즐겨한다. 이 카드 게임의 규칙은 다음과 같다.
- N개의 빨간색 카드가 있다. 각각의 카드는 순서대로 1부터 N까지 번호가 매겨져 있다. 이 중에서 M개의 카드를 고른다.
- N개의 파란색 카드가 있다. 각각의 카드는 순서대로 1부터 N까지 번호가 매겨져 있다. 이 중에서 빨간색에서 고른 번호와 같은 파란색 카드 M개를 고른다.
- 철수는 빨간색 카드를 가지고 민수는 파란색 카드를 가진다.
- 철수와 민수는 고른 카드 중에 1장을 뒤집어진 상태로 낸다. 그리고 카드를 다시 뒤집어서 번호가 큰 사람이 이긴다. 이 동작을 K번 해서 더 많이 이긴 사람이 최종적으로 승리한다. 한 번 낸 카드는 반드시 버려야 한다.
철수는 뛰어난 마술사이기 때문에 본인이 낼 카드를 마음대로 조작할 수 있다. 즉, 카드를 버리고 민수 몰래 다시 들고 온다거나 민수한테 없는 카드를 내기도 한다.
민수는 뛰어난 심리학자이기 때문에 철수가 낼 카드를 알아낼 수 있다. 그래서 민수는 철수가 낼 카드보다 큰 카드가 있다면 그 카드들 중 가장 작은 카드를 내기로 했다.
K번 동안 철수가 낼 카드가 입력으로 주어진다. 그렇다면 민수가 어떤 카드를 낼지 출력하라. 단, 민수가 카드를 내지 못하는 경우는 없다고 가정한다.
[입력]
첫째 줄에 세 개의 자연수 N, M, K가 주어진다. (1 ≤ M ≤ N ≤ 4,000,000, 1 ≤ K ≤ min(M, 10,000))
다음 줄에 카드의 번호를 나타내는 M개의 자연수가 주어진다. 각각의 수들은 1 이상이고 N 이하이며 서로 다르다.
다음 줄에 K개의 자연수가 주어진다. i번째 수는 철수가 i번째로 내는 카드의 번호이다. 철수가 내는 카드 역시 1 이상 N 이하이다.
[출력]
K줄에 걸쳐서 수를 출력한다. i번째 줄에는 민수가 i번째로 낼 카드의 번호가 출력되어야 한다.
[아이디어]
1) 카드의 사용 여부를 판별하기 위해 분리집합을 활용한다.
2) 0~N까지 수에 대한 root 배열 r을 모든 원소가 0이 되도록 생성한 뒤, 실제 사용되는 M개의 카드(cards)에 대해서만 root를 자기 자신으로 업데이트 해준다.
3) 이분 탐색 bisect_right으로 철수가 내는 카드보다 큰 카드를 탐색하게 하되, 그 카드가 사용할 수 없는 카드인 경우 다음 index를 탐색할 수 있도록 한다.
4) root가 0이 아닌 카드라면 내고, 냈다는 것을 표현하기 위해 원래의 root보다 1 큰 수로 업데이트한다. (root+1의 수가 cards에 있다면 다음 후보로 사용될 것이고, 그렇지 않으면 root가 0으로 업데이트 되는 효과가 있다.)
import sys
import bisect as bi
sys.setrecursionlimit(10**4)
input=sys.stdin.readline
n,m,k = map(int,input().split())
cards = list(map(int,input().split()))
minsu = list(map(int,input().split()))
r = [0]*(n+1)
cards.sort()
for x in cards:
r[x] = x
def root(x):
if r[x]==x:
return x
r[x]=root(r[x])
return r[x]
for x in minsu:
t = bi.bisect_right(cards,x)
while root(cards[t])==0:
t+=1
tmp = root(cards[t])
print(tmp)
r[cards[t]] = tmp + 1
'백준(Python) > 자료구조' 카테고리의 다른 글
[코딩 테스트 연습(파이썬/Python)] 백준(BOJ) 3015번 _ 오아시스 재결합 (0) | 2022.04.16 |
---|---|
[코딩 테스트 연습(파이썬/Python)] 백준 2143번 _ 두 배열의 합 (0) | 2022.03.13 |
[코딩 테스트 연습(파이썬/Python)] 백준 10775번 _ 공항 (0) | 2022.03.10 |
[코딩 테스트 연습(파이썬/Python)] 백준(BOJ) 20040번 _ 사이클 게임 (0) | 2022.02.17 |
[코딩 테스트 연습(파이썬/Python)] 백준 1717번 _ 집합의 표현 (0) | 2022.01.04 |