문제
김형택은 지금 몰래 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
입력 | 출력 |
10 8 | 1 |
100 80 | 6 |
47 47 | -1 |
99000 0 | 1000 |
1000000000 470000000 | 19230770 |
나의 풀이
[Python(파이썬)]
풀이 1 - 시간 초과
total, win = map(int, input().split())
percent, time, temp = int(win / total * 100), 0, 0
if total == win:
print(-1)
else:
for i in range(1, 1000000000):
temp = int((win+i) / (total+i) * 100)
time += 1
if percent != temp:
print(time)
break
풀이 2 - 이진 탐색 풀이 (다른 사람 풀이 참조)
total, win = map(int, input().split())
percent = win * 100 // total
first, last = 1, total
if percent >= 99:
print(-1)
else:
while first <= last:
mid = (first + last) // 2
if (win+mid) * 100 // (total+mid) <= percent:
first = mid + 1
else:
answer = mid
last = mid - 1
print(answer)
풀이 과정
이 문제는 시간 초과가 안 나오게 하는 것이 관건인 문제인 것 같다.
처음에는 이진탐색을 생각하지 않고 그냥 한개씩 더해가면서 풀었더니 시간초과가 나왔다.
1 ≤ X ≤ 1,000,000,000 범위가 너무 커서 숫자가 커질 수록 시간이 많이 드는 것이었다.
그래서 방법을 찾아보다 이 문제는 이진탐색(이분 탐색) 알고리즘을 통해 풀어야하는 것을 알았다.
이진 탐색 알고리즘을 통해 처음 문제를 풀다보니 어려움을 겪고 다른 사람들의 풀이를 보면서 학습하며 풀었다.
[Algorithm] 이진 탐색(Binary Search, 이분 탐색, 이진 검색)
이진 탐색(Binary Search) 정렬된 데이터 집합을 이분화하면서 특정한 값을 탐색하는 검색 알고리즘 -> 자료들이 순서대로 정리되어 있을 때 원하는 값을 찾기 위해 자료를 반씩 나누어 살펴보는 방
young-library.tistory.com
문제를 풀면서 발생한 또 한가지 문제는 승률 구하는 방법에서 생겼다.
승률을 구하는 방법에는 두가지 방법이 있다.
1. int(win / total * 100)
2. win * 100 // total
이 문제에서는 1번째 방법 int(win / total * 100) 을 사용해서 구현하니 틀렸다고 나왔다.
>>> 58 / 100
0.58
>>> 58/100*100
57.99999999999999
>>> int(58/100*100)
57
>>> 29 / 50
0.58
>>> 29 / 50 * 100
57.99999999999999
위와 같이 58 / 100 한다음 100을 곱해주면 58이 나와야하는데 57이 나오는 것이다.
글 읽기 - 29/50=0.58과 29/50*100=57.9999999 (acmicpc.net)
글 읽기 - 29/50=0.58과 29/50*100=57.9999999
댓글을 작성하려면 로그인해야 합니다.
www.acmicpc.net
파이썬에서 실수 자료형은 정확한 수를 담지 않는다고 한다. 따라서 위 문제를 해결하기위해
2번 win * 100 // total 로 승률을 구해야한다.
문제 출처
1072번: 게임
김형택은 지금 몰래 Spider Solitaire(스파이더 카드놀이)를 하고 있다. 형택이는 이 게임을 이길 때도 있었지만, 질 때도 있었다. 누군가의 시선이 느껴진 형택이는 게임을 중단하고 코딩을 하기 시
www.acmicpc.net
'[Python] Baekjoon > Brute force(브루트포스)' 카테고리의 다른 글
[백준(Baekjoon)] 1431 시리얼 번호 (0) | 2021.10.11 |
---|---|
[백준(Baekjoon)] 1051 숫자 정사각형 (0) | 2021.10.10 |
[백준(Baekjoon)] 2502 떡 먹는 호랑이 (0) | 2021.10.07 |
[백준(Baekjoon)] 2033 반올림 (0) | 2021.10.06 |
[백준(Baekjoon)] 1157 단어 공부 (0) | 2021.10.06 |
댓글