Algorithm/백준 알고리즘 파이썬(int-i)
[1417]국회의원 선거
이숨인
2023. 7. 26. 15:16
1. 문제
2. 알고리즘 + 풀이
초기 코드 ->
# -*- coding: euc-kr -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'utf-8')
N = int(input())
lst = [0] * N #이렇게 초기화를 해야지, 대입 연산자 사용 가능
cnt = 0
for i in range(N):
lst[i] = int(input())
key = lst[0] #다솜이가 기준
for i in range(1,N): #i=0이 다솜이 -> i=1부터 탐색
if (key <= lst[i]):
while not (key > lst[i]):
lst[i]-=1
key +=1
cnt+=1
print(cnt)
- 다솜이는 기호 1번 후보 => 따라서 코드에서 key = lst[0]는, 다솜이가 받은 득표 수 의미
- lst[i]에서 i는 각각의 후보를 의미하고 lst[i]의 값은 해당 후보가 받은 표의 수입니다.
- while not (key > lst[i]) 루프 안에서 lst[i]-=1와 cnt+=1이 실행되는 것은 다솜이가 다른 후보보다 많은 표를 얻기 위해 필요한 최소한의 매수 수를 계산하는 것
=> 입력 예시처럼 잘 나왔지만, 백준에서 틀렸다고 채점되었다
'최소 매수'를 구해야 한다는 것을 생각 안한 듯 하여, 반례를 찾아봄
7787 일 경우, 7787 -> 8687 -> 9677 로 총 2번 매수해야 한다.(sort하지 않고, 순서대로 한다면)
반례) BUT 2번 매수할 필요가 없음 => 최소로 매수해야 하므로 7787 -> 8777 로 매수할 수가 있다!
즉, 최소 매수를 위해서는 최대를 찾아야 했다!
수정한 코드
N = int(input())
lst = [0] * N #이렇게 초기화를 해야지, 대입 연산자 사용 가능
cnt = 0
for i in range(N): #i=0,1,...N-1
lst[i] = int(input())
key = lst[0] #다솜이가 기준
others = lst[1:]
others.sort(reverse=True) #나머지 후보들 득표수 내림차순 정렬
while (key <= others[0]):
others[0]-=1
key +=1
cnt+=1
others.sort(reverse=True)
print(cnt)
=> 런타임 에러 발생
런타임 에러 발생 이유
others 리스트가 비어 있는 경우에 others[0]를 참조하려고 시도하기 때문
N = int(input())
lst = [0] * N #이렇게 초기화를 해야지, 대입 연산자 사용 가능
cnt = 0
for i in range(N): #i=0,1,...N-1
lst[i] = int(input())
key = lst[0] #다솜이가 기준
others = lst[1:]
others.sort(reverse=True) #나머지 후보들 득표수 내림차순 정렬
while others and key <= others[0]: # others가 비어있지 않고, 다솜이가 가장 많은 표를 가질 때까지
others[0]-=1
key +=1
cnt+=1
others.sort(reverse=True)
print(cnt)
while others and key <= others[0]:
others 리스트가 비어 있지 않고, 다솜이의 득표 수가 가장 많은 후보의 득표 수 이하일 때만 while 루프를 계속 실행하도록 함.
=> 이렇게 하면 others 리스트가 비어 있을 때 others[0]에 접근하려는 시도를 방지할 수 있다.
최종 코드(성공)
N = int(input())
lst = [0] * N #이렇게 초기화를 해야지, 대입 연산자 사용 가능
cnt = 0
for i in range(N): #i=0,1,...N-1
lst[i] = int(input())
key = lst[0] #다솜이가 기준
others = lst[1:]
others.sort(reverse=True) #나머지 후보들 득표수 내림차순 정렬
while (key <= others[0]):
others[0]-=1
key +=1
cnt+=1
others.sort(reverse=True)
print(cnt)
라이싱