Problem Solving/BOJ

[BOJ][Python]18110 풀이

NoiB 2023. 7. 20. 21:32
반응형

https://www.acmicpc.net/problem/18110

 

18110번: solved.ac

5명의 15%는 0.75명으로, 이를 반올림하면 1명이다. 따라서 solved.ac는 가장 높은 난이도 의견과 가장 낮은 난이도 의견을 하나씩 제외하고, {5, 5, 7}에 대한 평균으로 문제 난이도를 결정한다.

www.acmicpc.net

import sys
ssr = sys.stdin.readline

n = int(ssr())
scores = [int(ssr()) for _ in range(n)]
scores.sort()
if n == 0:
    print(0)
elif n < 4:
    print(round(sum(scores)/len(scores) + 1e-7))
else:
    cut = round(n*15/100 + 1e-7)
    print(round(sum(scores[cut:-cut])/len(scores[cut:-cut]) + 1e-7))
    
'''
f-string 도 오사오입을 따른다
print(sum([8, 8, 17, 22][1:-1]))
print(25/2)
print(f'{23/2:.0f}')
print(f'{2.5:.0f}')
print(f'{2.25:.1f}')
'''

오늘은 문제 풀이에 앞서서 사과를 먼저 드려야 할 것 같습니다. 예전에 f-string을 이용한 문자열 포맷팅 방법을 사용하면 파이썬의 round 함수에서 생기는 반올림 규칙인 오사오입(반올림 자릿수가 5일 때 바로 앞 자리가 가까운 짝수로 반올림)이 아니라 사사오입(우리가 흔히 아는 반올림)으로 할 수 있다고 말씀을 드렸는데, 오늘 해당 문제를 풀어보면서 문자열 포맷팅으로 진행을 했더니 WA가 나와서 직접 하나씩 찍어보니까 문자열 포맷팅도 오사오입을 따르더라구요. 근시일내로 문자열 포맷팅을 이용했던 방법들을 전부 고쳐놓겠습니다. 혹시라도 제 포스팅 때문에 혼동이 오셨을 분들께 죄송합니다.

 

그래서 해당 문제는 오사오입을 해결하기 위해 해당 문제의 입력에서 나올 수 있는 최대 입력 3*(10^5)을 절사했을 때의 최대길이 210000으로 나눴을 때 나올 수 있는 가장 작은 소수점 값을 구하기 위해 1/210000 = 4.7e-6 보다 작은 값을 반올림을 하려는 값에 더해서 계산 자체에는 영향을 주지 않으면서 반올림을 우리가 원하는 방향으로 진행할 수 있도록 하는 방법을 사용했습니다. 개인적으로 좋아하지 않는 방법이지만 파이썬 자체적으로 해결할 방법이 없기 때문에 이런 방법을 사용해야 할 것 같습니다.

반응형