BeakJoon 1072. 게임 - 승률 변화 계산하기
실수의 정수형 타입캐스팅은 부정확할 수 있다. 따라서 퍼센트를 계산할 때 정수로만 계산될 수 있도록 한다
문제 URL: https://www.acmicpc.net/problem/1072
😒문제
김형택은 지금 몰래 Spider Solitaire(스파이더 카드놀이)를 하고 있다. 형택이는 이 게임을 이길 때도 있었지만, 질 때도 있었다. 누군가의 시선이 느껴진 형택이는 게임을 중단하고 코딩을 하기 시작했다. 의심을 피했다고 생각한 형택이는 다시 게임을 켰다. 그 때 형택이는 잠시 코딩을 하는 사이에 자신의 게임 실력이 눈에 띄게 향상된 것을 알았다.
이제 형택이는 앞으로의 모든 게임에서 지지 않는다. 하지만, 형택이는 게임 기록을 삭제 할 수 없기 때문에, 자신의 못하던 예전 기록이 현재 자신의 엄청난 실력을 증명하지 못한다고 생각했다.
게임 기록은 다음과 같이 생겼다.
- 게임 횟수 : X
- 이긴 게임 : Y (Z%)
- Z는 형택이의 승률이고, 소수점은 버린다. 예를 들어, X=53, Y=47이라면, Z=88이다.
X와 Y가 주어졌을 때, 형택이가 게임을 최소 몇 번 더 해야 Z가 변하는지 구하는 프로그램을 작성하시오.
👀제약조건
각 줄에 정수 X와 Y가 주어진다.
입력
각 줄에 정수 X와 Y가 주어진다.
출력
첫째 줄에 형택이가 게임을 최소 몇 판 더 해야하는지 출력한다. 만약 Z가 절대 변하지 않는다면 -1을 출력한다.
제한
- 1 ≤ X ≤ 1,000,000,000
- 0 ≤ Y ≤ X
예제 입력 1
1
2
10 8
예제 출력 1
1
2
1
예제 입력 2
1
2
100 80
예제 출력 2
1
2
6
예제 입력 3
1
2
47 47
예제 출력 3
1
2
-1
예제 입력 4
1
2
99000 0
예제 출력 4
1
2
1000
예제 입력 5
1
2
1000000000 470000000
예제 출력 5
1
19230770
🤩접근방법
X의 범위가 1,000,000,000
이므로 시간복잡도를 고려하여 확률이 변화를 위해 필요한 게임의 수가 몇 개인지 이분탐색으로 확인합니다.
만약 확률이 99퍼센트
이상이라면 몇번의 게임을 진행하더라도 확률이 더 높아지지 않기 때문에 -1
을 출력할 수 있도록 합니다.
🤔풀이
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def check(mid, temp_X):
global Z
z = mid * 100 // temp_X
if z > Z:
return True
else:
return False
X,Y = map(int, input().split())
Z = Y * 100 // X
left = 0
right = 1000000000
while left + 1 < right:
#추가 게임 수
mid = (left + right) // 2
if (Y+mid) * 100 // (X+mid) > Z:
right = mid
else:
left = mid
if Z >= 99:
print(-1)
else:
print(right)
🧐
퍼센트는 int( (Y/X) * 100 )
로 계산시 실수의 연산
및 정수로 타입캐스팅
시 값이 위 이미지와 같이 부정확하게 계산될 수 있습니다.
그 이유는 어떤 실수들은 이진법으로 정확하게 표현이 불가하기 때문에 근사값을 사용하기 때문입니다.
- 파이썬에서는 유효숫자e지수 방법으로 부동소수점 형태를 직접 표현합니다.
- $유효숫자e지수 = 유효숫자X10^{지수}$
- 123e2 # 123e2 = 123.0 x 100 = 12300.0
- 123.456e-3 # 123.456e-3 = 123.456 x 0.001 = 0.123456
- 부동소수점의 오차
- 0.1을 이진법으로 나타내면 0011(2)이 무한히 반복되는 실수가 됩니다.
컴퓨터에서는 하나의 숫자를 나타내기 위한 메모리의 크기가 제한이 되어 있기 때문에 특정 소수점 이하는 생략하고 가장 비슷한 숫자로 표현할 수 밖에 없습니다. 따라서
0.1=0.0001100110011001100110011001100110011001100110…
값은0.1≈0.1000000000000000055511151231257827021181583
으로 저장됩니다.파이썬 콘솔에서 0.1을 입력하면 0.1로 나타나는 이유는 REPL 인터페이스에서 값이 출력될 때 편의상 일정 소수점 이하를 생략하고 보여주기 때문입니다. 이러한 이유로 0.1 + 0.2 == 0.3 와 같은 비교는 False가됩니다. 실제로
0.1+0.2 = 0.2999999999999999888977697537484345957636833190
- 따라서 실수를 비교할 때는 round 명령을 사용하여 유효숫자를 지정한 반올림 후 비교해야합니다.
- 참고
따라서 정수로만 퍼센트를 계산할 수 있도록 Y * 100 // X
의 순서로 계산해야합니다.