[백준][Python] 18110. solved.ac
Silver Ⅳ 🔗18110. solved.ac
📝문제 요약
문제
solved.ac는 Sogang ICPC Team 학회원들의 알고리즘 공부에 도움을 주고자 만든 서비스이다. 지금은 서강대뿐만 아니라 수많은 사람들이 solved.ac의 도움을 받아 알고리즘 공부를 하고 있다.
ICPC Team은 백준 온라인 저지에서 문제풀이를 연습하는데, 백준 온라인 저지의 문제들에는 난이도 표기가 없어서, 지금까지는 다양한 문제를 풀어 보고 싶더라도 난이도를 가늠하기 어려워 무슨 문제를 풀어야 할지 판단하기 곤란했기 때문에 solved.ac가 만들어졌다. solved.ac가 생긴 이후 전국에서 200명 이상의 기여자 분들께서 소중한 난이도 의견을 공유해 주셨고, 지금은 약 7,000문제에 난이도 표기가 붙게 되었다.
어떤 문제의 난이도는 그 문제를 푼 사람들이 제출한 난이도 의견을 바탕으로 결정한다. 난이도 의견은 그 사용자가 생각한 난이도를 의미하는 정수 하나로 주어진다. solved.ac가 사용자들의 의견을 바탕으로 난이도를 결정하는 방식은 다음과 같다.
- 아직 아무 의견이 없다면 문제의 난이도는 0으로 결정한다.
- 의견이 하나 이상 있다면, 문제의 난이도는 모든 사람의 난이도 의견의 30% 절사평균으로 결정한다.
절사평균이란 극단적인 값들이 평균을 왜곡하는 것을 막기 위해 가장 큰 값들과 가장 작은 값들을 제외하고 평균을 내는 것을 말한다. 30% 절사평균의 경우 위에서 15%, 아래에서 15%를 각각 제외하고 평균을 계산한다. 따라서 20명이 투표했다면, 가장 높은 난이도에 투표한 3명과 가장 낮은 난이도에 투표한 3명의 투표는 평균 계산에 반영하지 않는다는 것이다.
제외되는 사람의 수는 위, 아래에서 각각 반올림한다. 25명이 투표한 경우 위, 아래에서 각각 3.75명을 제외해야 하는데, 이 경우 반올림해 4명씩을 제외한다.
마지막으로, 계산된 평균도 정수로 반올림된다. 절사평균이 16.7이었다면 최종 난이도는 17이 된다.
사용자들이 어떤 문제에 제출한 난이도 의견 목록이 주어질 때, solved.ac가 결정한 문제의 난이도를 계산하는 프로그램을 작성하시오.
입력
첫 번째 줄에 난이도 의견의 개수 n이 주어진다. (0 ≤ n ≤ 3 × 105)
이후 두 번째 줄부터 1 + n번째 줄까지 사용자들이 제출한 난이도 의견 n개가 한 줄에 하나씩 주어진다. 모든 난이도 의견은 1 이상 30 이하이다.
출력
solved.ac가 계산한 문제의 난이도를 출력한다.
✏️문제 풀이
1번 풀이(❌틀렸습니다)
n = int(input())
opinions = [int(input()) for _ in range(n)]
if n == 0:
print(0)
else :
opinions.sort()
trimmed_opinions = opinions[int(round(n*0.15)):n-int(round(n*0.15))]
avg = round(sum(trimmed_opinions)/len(trimmed_opinions))
print(avg)
round
를 이용하면 간단하게 구현이 가능하다고 생각하지만 파이썬의 round는 사사오입이 아니고 오사오입으로 처리- 사사오입 : 4 이하의 숫자는 내림, 5 이상의 숫자는 올림
- 오사오입 : 5 미만의 숫자는 내림, 5 초과의 숫자는 올림
-
이러한 문제로 직접 반올림을 하는 함수 필요
def trim_round(n): if n - int(n) >= 0.5: return int(n) + 1 else: return int(n)
2번 풀이(⌛시간 초과)
n = int(input())
opinions = [int(input()) for _ in range(n)]
def trim_round(n):
if n - int(n) >= 0.5:
return int(n) + 1
else:
return int(n)
if n == 0:
print(0)
else :
opinions.sort()
trim_cnt = trim_round(n*0.15)
trimmed_opinions = opinions[trim_cnt:n-trim_cnt]
avg = trim_round(sum(trimmed_opinions)/len(trimmed_opinions))
print(avg)
- 해결 방법
- 보통 시간 초과가 났을 경우 가장 먼저 시도하는 방법은
sys.stdin.readline
을 사용하는 것이어서 사용하여 문제 해결
- 보통 시간 초과가 났을 경우 가장 먼저 시도하는 방법은
최종 풀이
- sys 라이브러리를 불러오고 input 값을
sys.stdin.readline
로 사용 - 입력
- 의견의 개수
n
입력 - n개의 의견을
opinions
리스트에 저장
- 의견의 개수
- 반올림을 위한
trim_round()
함수 선언n - int(n) >= 0.5
: 정수를 제외한 소수점이 0.5보다 크면- 올림 :
int(n)+1
을 반환
- 올림 :
- 그렇지 않다면
- 내림 :
int(n)
을 반환
- 내림 :
n
이 0이라면 의견이 없으므로 0을 반환- 그렇지 않은 경우에는
opinions
리스트를 오름차순 정렬- 절사를 위한 변수
trim_cnt
는n*0.15
을 반올림하여 나타냄- 여기서 반올림은 위에서 선언한
trim_round()
를 사용
- 여기서 반올림은 위에서 선언한
- 절사한 의견(
rimmed_opinions
)은opinions
의trim_cnt
번째 인덱스부터n-trim_cnt-1
까지 - 평균값을 구함 : 평균값은 반올림을 해야하므로
trim_round()
를 사용 - 평균값 반환
코드와 함께 보는 풀이
# 입력 속도 향상을 위한 sys.stdin.readline 사용
import sys
input = sys.stdin.readline
# 난이도 의견의 개수 입력
n = int(input())
# n개의 난이도 의견 입력받기
opinions = [int(input()) for _ in range(n)]
# 반올림 함수 정의
def trim_round(n):
# 0.5 이상일 때 올림
if n - int(n) >= 0.5:
return int(n) + 1
# 0.5 미만일 때 내림
else:
return int(n)
# 의견이 없는 경우 난이도는 0
if n == 0:
print(0)
else:
# 의견들을 오름차순으로 정렬
opinions.sort()
# 제외할 의견의 개수 계산 (30% 절사평균)
# 위아래 각각 15%씩 제외
trim_cnt = trim_round(n*0.15)
# 절사평균을 적용한 의견들 선택
# trim_cnt부터 n-trim_cnt까지의 의견만 사용
trimmed_opinions = opinions[trim_cnt:n-trim_cnt]
# 절사평균 계산 및 반올림
avg = trim_round(sum(trimmed_opinions)/len(trimmed_opinions))
# 최종 난이도 출력
print(avg)
💯제출 코드
import sys
input = sys.stdin.readline
n = int(input())
opinions = [int(input()) for _ in range(n)]
def trim_round(n):
if n - int(n) >= 0.5:
return int(n) + 1
else:
return int(n)
if n == 0:
print(0)
else :
opinions.sort()
trim_cnt = trim_round(n*0.15)
trimmed_opinions = opinions[trim_cnt:n-trim_cnt]
avg = trim_round(sum(trimmed_opinions)/len(trimmed_opinions))
print(avg)
댓글남기기