import math
def get_winning_rate(x, y):
return (y * 100) // x
x, y = map(int, input().split())
z = get_winning_rate(x, y) # 승률. 구할때는 소수점 버림
start, end = 1, x
result = 0
if z >= 99:
print(-1)
else:
while start <= end:
mid = (start + end) // 2
temp_z = get_winning_rate(x + mid, y + mid)
if temp_z > z: # 승률이 변했을경우. 변하는 경우중에 최소값을 찾아야하기때문에 왼쪽범위 탐색
end = mid - 1
result = mid
else: # 승률이 계속 같다면 게임을 더 해야함. 오른쪽 범위 탐색
start = mid + 1
print(result)
게임 플레이 횟수와 게임을 이긴 수가 주어졌을때, 최소 몇게임을 더 해야 승률이 올라가는지에 대한 문자였다.
이분 탐색을 사용했고 최소 1판에서 최대 x판을 범위로 잡았다.
중간값을 x와 y에 각각 더해주고 승률을 구해준 다음 결과가 z와 다를때까지 반복한다.
엣지 케이스를 찾는 것이 조금 어려웠는데, z가 절대 변하지 않는 경우에는 -1을 리턴해야했다. 승률이 이미 99 이상인 경우 변하지 않기때문에 이 경우를 먼저 판단해주었다.
문제를 풀면서 승률을 계산할때 처음에는 math.trunc((y / x) * 100)을 사용했는데 테스트 케이스는 모두 통과했지만 제출 결과에서는 계속 틀렸다고 나왔다. 계산 방법이 틀린건 아니라고 생각해서 이해가 되질 않았는데 찾아보다보니 나눗셈 연산의 처리 방식이 달라서 계산이 잘못되었던 것 같다.
(y * 100) // x 의 경우, 파이썬은 정수 나눗셈 연산을 하는데 y * 100을 먼저 한 뒤 x로 나눈 몫을 구하게 된다. 이때 소수점 이하가 버려지고 정수 몫만 남는다.
math.trunc((y / x) * 100)은 실수 나눗셈을 수행한 후에 결과를 정수로 변환한다. y / x는 실수 값을 반환하고, 이 값에 100을 곱하고 math.trunc() 함수를 사용하여 정수 부분을 남기게 된다.
파이썬에서의 정수 나눗셈은 소수점 이하를 버리고 정수 부분을 남기는 것이다. 내가 처음에 썼던 연산은 정확한 실수값을 계산한 후에 필요에 따라 정수 부분을 남기는 방식이라 계속 잘못된 값이 나왔던 거였다. 연산방식에도 차이가 있다고는 생각하지 못했는데...^.ㅠ 이 부분이 예상외로 어려웠던 문제였다.
https://www.acmicpc.net/problem/1072
'study > Algorithm' 카테고리의 다른 글
[백준] 파이썬 2304 : 창고 다각형 (0) | 2024.04.09 |
---|---|
[백준] 파이썬 2108 : 통계학 (0) | 2024.04.09 |
[백준] 파이썬 2110번 : 공유기 설치 (0) | 2024.04.05 |
[백준] 파이썬 2470번: 두 용액 (1) | 2024.04.05 |
[백준] 파이썬 3079번: 입국심사 (0) | 2024.04.05 |