[알고리즘 스터디 - 1주차 3] 소수 게임
난이도
Gold 4
문제
인하대학교에 다니는 대웅이는 정수론을 정말 좋아한다. 정수론을 광적으로 좋아하는 대웅이는 어느 순간부터 소수를 외우기 시작했고 어떤 수를 말하면 그 수가 소수인지 아닌지 판별할 수 있는 능력을 가지게 되었다. 인하대학교에 소수의 신이 있다는 소문이 퍼지자 인상대학교의 소수 마스터 규성이는 대웅이에게 도전장을 내밀었다.
둘은 누가 더 소수를 사랑하는지 내기를 하기로 하였다.
하지만 누가 더 소수를 사랑하는지에 대한 기준이 없으므로 소수 게임을 이용하기로 하였다.
소수게임의 규칙은 다음과 같다.
두 사람이 번갈아가며 소수를 말한다. 소수가 아닌 수를 부르게 될 경우 상대방은 지금까지 상대방이 말한 소수중에서 3번째로 큰 수만큼 점수를 얻게 된다.(만약 상대방이 지금까지 말한 소수가 3개 미만이라면 상대방은 1000점을 얻게 된다.) 만약 지금까지 한번이라도 등장한 소수를 말할 경우 해당 소수를 말한 팀이 -1000을 얻게 되며 해당 소수는 그 사람이 말한 소수로 기록되지 않는다. 규성이는 도전자이므로 게임은 항상 대웅이부터 시작한다. 두 사람이 말할 수 있는 소수는 항상 5000000 미만이다. 다음과 같은 규칙으로 소수 게임을 진행할 때 승자를 출력하시오.
입력
입력의 첫째 줄에 두 사람이 대결을 하는 라운드 수 N이 주어진다. (5≤N≤100,000)
이 후 N개의 줄에 대웅이와 규성이가 말하는 정수가 공백으로 구분되어 주어진다. 두 사람이 말하는 정수는 5,000,000보다 작은 자연수 또는 0이다.
출력
대웅이가 이길 경우 “소수의 신 갓대웅” 규성이가 이길 경우 “소수 마스터 갓규성”을 출력한다. 만약 비길 경우 “우열을 가릴 수 없음” 을 출력한다.
예제 입력
5
2 3
4 9
2 10
7 37
11 3
예제 출력
소수의 신 갓대웅
해설 및 후기
우선 최대 정수의 크기가 주어졌으므로 해당 크기만큼 에라토스테네스의 체를 이용하여 소수 판별이 가능하도록 한다. 다음으로 최대 힙(최소 힙의 변형)을 사용하여 소수게임의 규칙 “2. 상대방이 말한 소수 중에서 3번째로 큰 수만큼 전수를 얻게 된다.”를 처리할 수 있도록 한다. 또한 in을 이용해 해당 소수가 사용되었는지를 판별하는 것이 아닌 에라토스테네스의 체 자체에서 사용 여부를 판별할 수 있도록 하여 O(1)시간으로 사용 여부를 판별할 수 있도록 한다.
제출 코드
import heapq as h
import sys
era = [[False, False] for _ in range(5000001)]
era[0][0] = True
era[1][0] = True
a = 0
b = 0
for i in range(2, int(5000000**0.5)+1):
if(era[i][0]):
continue
tmp = 2
while(tmp*i <= 5000000):
era[tmp*i][0] = True
tmp += 1
n = int(sys.stdin.readline().rstrip())
heapA = []
heapB = []
def getNum(hp): #상대가 얻는 점수
if(len(hp)<3):
return 1000
h1 = h.heappop(hp)
h2 = h.heappop(hp)
h3 = h.heappop(hp)
h.heappush(hp,h1)
h.heappush(hp,h2)
h.heappush(hp,h3)
return h3*-1
for i in range(n):
x, y = map(int, sys.stdin.readline().rstrip().split())
if(not era[x][0] and not era[x][1]): #소수이며 첫 번째로 사용
h.heappush(heapA, x*-1)
era[x][1] = True
else:
if(era[x][0]): #소수가 아님
b += getNum(heapB)
else:
a -= 1000
if(not era[y][0] and not era[y][1]):
h.heappush(heapB, y*-1)
era[y][1] = True
else:
if(era[y][0]):
a += getNum(heapA)
else:
b -= 1000
if(a>b):
print('소수의 신 갓대웅')
elif(a<b):
print("소수 마스터 갓규성")
else:
print("우열을 가릴 수 없음")