문제 링크
문제 요약
두 명의 플레이어 Vilius와 Adomas가 가위바위보 게임을 합니다. 각 플레이어는 가위, 바위, 보를 몇 번 냈는지 총 횟수는 알지만, 어떤 순서로 냈는지는 기억하지 못합니다. 게임의 점수 체계는 다음과 같습니다: Vilius가 이기면 +1점, Vilius가 지면 -1점, 비기면 0점입니다. 주어진 가위, 바위, 보 횟수를 바탕으로 Vilius가 얻을 수 있는 최대 점수와 최소 점수를 계산해야 합니다.
풀이
이 문제는 주어진 가위, 바위, 보의 총 횟수만 중요하고, 어떤 순서로 냈는지는 중요하지 않다는 점을 이용한 그리디(Greedy) 문제입니다. Vilius의 점수를 최대로 만들거나 최소로 만드는 두 가지 시나리오를 각각 고려하여 풀이할 수 있습니다.
Vilius의 점수를 최대로 만드는 경우: Vilius의 점수를 최대로 만들기 위해서는 Vilius가 이기는 경우(+1점)를 최대한 많이 발생시켜야 합니다. 그 다음으로는 점수에 영향을 주지 않는 비기는 경우(0점)를 처리하고, 마지막으로 점수를 잃는 지는 경우(-1점)를 최소화해야 합니다.
Vilius의 점수를 최소로 만드는 경우: Vilius의 점수를 최소로 만들기 위해서는 Vilius가 지는 경우(-1점)를 최대한 많이 발생시켜야 합니다. 그 다음으로는 점수에 영향을 주지 않는 비기는 경우(0점)를 처리하고, 마지막으로 점수를 얻는 이기는 경우(+1점)를 최소화해야 합니다.
정답 코드
def win(a, b):
# 최대한 이길 수 있게 하기
ret = 0
for i in range(3):
k = min(a[i], b[(i + 2) % 3])
a[i] -= k
b[(i + 2) % 3] -= k
ret += k
return ret
def tie(a, b):
# 최대한 비기게 하기
for i in range(3):
k = min(a[i], b[i])
a[i] -= k
b[i] -= k
def lose(a, b):
# 최대한 지도록 하기
ret = 0
for i in range(3):
k = min(a[i], b[(i + 1) % 3])
a[i] -= k
b[(i + 1) % 3] -= k
ret -= k
return ret
def greedy_win(a, b):
# Vilius가 이기는 경우를 최대로, 지는 경우를 최소로
ret = 0
ret += win(a, b) # Vilius가 이김
tie(a, b) # 비김 (점수 영향 없음)
ret += lose(a, b) # Vilius가 짐
return ret
def greedy_lose(a, b):
# Vilius가 지는 경우를 최대로, 이기는 경우를 최소로
ret = 0
ret += lose(a, b) # Vilius가 짐
tie(a, b) # 비김 (점수 영향 없음)
ret += win(a, b) # Vilius가 이김
return ret
def solve():
A = [*map(int, input().split())] # Vilius의 바위, 보, 가위 횟수 (0: 바위, 1: 보, 2: 가위)
B = [*map(int, input().split())] # Adomas의 바위, 보, 가위 횟수
# 최대 점수 계산 (A, B 리스트는 함수 내에서 변경되므로 복사본 전달)
max_score = greedy_win(A[::], B[::])
# 최소 점수 계산 (A, B 리스트는 함수 내에서 변경되므로 복사본 전달)
min_score = greedy_lose(A[::], B[::])
print(max_score)
print(min_score)
if __name__ == "__main__":
tc = 1
for t in range(1, tc+1):
ret = solve()