백준 1072번 파이썬 문제풀이
- CS/BOJ
- 2021. 9. 5.
문제
김형택은 지금 몰래 Spider Solitaire(스파이더 카드놀이)를 하고 있다. 형택이는 이 게임을 이길 때도 있었지만, 질 때도 있었다. 누군가의 시선이 느껴진 형택이는 게임을 중단하고 코딩을 하기 시작했다. 의심을 피했다고 생각한 형택이는 다시 게임을 켰다. 그 때 형택이는 잠시 코딩을 하는 사이에 자신의 게임 실력이 눈에 띄게 향상된 것을 알았다.
이제 형택이는 앞으로의 모든 게임에서 지지 않는다. 하지만, 형택이는 게임 기록을 삭제 할 수 없기 때문에, 자신의 못하던 예전 기록이 현재 자신의 엄청난 실력을 증명하지 못한다고 생각했다.
게임 기록은 다음과 같이 생겼다.
- 게임 횟수 : X
- 이긴 게임 : Y (Z%)
- Z는 형택이의 승률이고, 소수점은 버린다. 예를 들어, X=53, Y=47이라면, Z=88이다.
X와 Y가 주어졌을 때, 형택이가 게임을 최소 몇 번 더 해야 Z가 변하는지 구하는 프로그램을 작성하시오.
입력
각 줄에 정수 X와 Y가 주어진다.
출력
첫째 줄에 형택이가 게임을 최소 몇 판 더 해야하는지 출력한다. 만약 Z가 절대 변하지 않는다면 -1을 출력한다.
제한
- 1 ≤ X ≤ 1,000,000,000
- 0 ≤ Y ≤ X
문제풀이
게임을 최소 몇 번을 더 해야하는지를 확인하는 문제다. 예를 4번의 경우, 1001번은 조건을 만족, 1000도 조건을 만족하지만 999는 조건을 만족하지 않는다. 즉, 특정 조건을 만족하는 최소/최대 문제로 치환해서 풀 수 있기 때문에 이진탐색으로 접근이 가능하다.
먼저 절대로 Z가 바뀔 수 없는 히든 케이스를 특정해야한다. 내가 생각하기에는 다음 두 경우가 적절한 히든 케이스라고 생각한다.
- 이긴 횟수 = 경기 횟수, 즉 승률이 100%이기 때문에 승률이 더 오를 수 없다.
- 승률이 99%인 경우. 한 번이라도 졌었기 때문에 승률이 절대 100%가 될 수 없다.
위의 두 경우를 예외처리 해주면, 나머지는 이진 탐색으로 접근할 수 있다. 이진탐색은 다음과 같은 로직으로 만들 수 있다.
- 중앙값을 설정한다.
- 중앙값이 해당 조건을 만족하는지 확인한다.
- 만족하는지 여부에 따라 구간값을 재설정한다.
3-1. 만족할 경우, 계속 살펴봐야할 경우다. 최소값을 보는 것이기 때문에 R = M으로 설정한다.
3-2. 만족하지 않을 경우, 더 살펴보지 않아도 되는 경우다. L = M+1 로 접근한다 - 1~3을 L < R일 때까지 반복한다.
코드는 아래와 같이 작성할 수 있다.
import sys
# 특정값을 만족하는지 확인하는 구간
def sol(x,y,z,m) :
next_y = (y + m) * 100
next_x = (x + m)
next_z = next_y // next_x
if next_z == z :
return False
else :
return True
#변수 입력 구간
x,y = map(int,sys.stdin.readline().split())
z = (y * 100) // x
#예외 설정
if x==y :
print(-1)
elif z == 99 :
print(-1)
#이진 탐색 구간
else :
answer = 0
l,r = 0, sys.maxsize
while l < r :
m = (l + r ) // 2
if sol(x, y, z, m ) :
r = m
answer = m
else :
l = m + 1
print(answer)
'CS > BOJ' 카테고리의 다른 글
백준 2252 파이썬 문제풀이 (0) | 2021.09.05 |
---|---|
백준 2776번 파이썬 문제 풀이 (0) | 2021.09.05 |
백준 1654번 파이썬 문제풀이 (0) | 2021.09.05 |
백준 1939 파이썬 문제풀이 (0) | 2021.09.05 |
백준 2805번 파이썬 문제풀이 (0) | 2021.09.05 |