BOJ 18110 - solved.ac 링크
(2023.06.27 기준 S4)
난이도 의견이 없다면 난이도는 0, 아니면 모든 사람의 난이도 의견의 30% 절사평균이 난이도가 된다.
n개의 난이도 의견이 1 이상 30 이하로 주어질 때, 난이도 출력
절사평균을 구하기 위해 정렬 및 반올림
30% 절사평균은 위, 아래에서 15%를 제외해야 한다. 문제에서 실수 부분은 반올림해야 한다고 적혀있다. (물론, 사사오입)
그러므로 15%를 구하기 위해선 기준점 t를 round(n * (15 / 100) = n * 3 / 20)로 잡고
이를 정렬된 난이도 의견들에서 t부터 n - t + 1 (0-based index)까지의 합을 구해 총 개수인 n - t * 2로 나누어 round 함수를 적용하면 절사평균이 나온다.
Python의 반올림 기본 방식은 오사오입이다.
- 오사오입
반올림에서 5 미만의 숫자는 버림하며 5 초과의 숫자는 올림한다. 5의 경우에는 5의 앞자리가 홀수인 경우엔 올림을 하고 짝수인 경우엔 버림을 하여 짝수로 만들어준다. 예를 들어 53.45는 53.4로, 32.75는 32.8로 반올림한다. 이를 오사오입(round-to-nearest-even)이라고 한다. 자연과학 및 공학의 유효 숫자에서 많이 쓴다.
참고 링크그렇다면 사사오입을 사용하기 위해선?
- decimal 모듈 사용
decimal 정확한 십진법 사용을 위한 하나의 모듈인데 여기서 반올림 방식을 직접 지정할 수 있고 이는 type이 decimal.Decimal인 변수에 적용 가능하다.
단점은 너무 느리다. 그러므로 이는 반올림뿐만 아니라 정확한 실수 부분의 표현이 필요할 때 사용하자.import decimal decimal.getcontext().rounding = decimal.ROUND_HALF_UP # 반올림 print(round(0.5), round(1.5), round(1.45, 1)) # output : 0 2 1.4 print(round(decimal.Decimal('0.5'), 0), round(decimal.Decimal('1.5'), 0), round(decimal.Decimal('1.45'), 1)) # output : 1 2 1.5
- 5e-(반올림하고자 하는 소수점 자리 + 1) 더해서 버림하기
만약 정수 부분까지 반올림하고자 하면 5e-(0 + 1) = 5e-1 = 0.5를 더해서 버림하면 된다.
사사오입 반올림만을 위한다면 이 방법이 제일 간단하고 빠르다.print(round(0.5), round(1.5), round(1.45, 1)) # output : 0 2 1.4 print(round(0.5 + 5e-1), round(1.5 + 5e-1), round(1.45 + 5e-2, 1)) # output : 1 2 1.5
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n; cin >> n;
// 아직 아무 의견이 없다면 문제의 난이도는 0으로 결정한다.
if (!n){
cout << 0;
return 0;
}
// 의견이 하나 이상 있다면, 문제의 난이도는 모든 사람의 난이도 의견의 30% 절사평균으로 결정한다.
int a[n]; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a + n);
int t = round((float)(n * 3) / 20); // 15%
// 위, 아래에서 15%를 제외한 평균
int s = 0; for (int i = t; i + t < n; i++) s += a[i];
int m = round((float)s / (n - t * 2));
cout << m;
}
n, *a = map(int, open(0))
# 아직 아무 의견이 없다면 문제의 난이도는 0으로 결정한다.
if not n:
print(0)
exit()
# 의견이 하나 이상 있다면, 문제의 난이도는 모든 사람의 난이도 의견의 30% 절사평균으로 결정한다.
# round 함수는 오사오입이므로 0.5를 더해 버림하는 방식을 사용하자.
t = int(n * 3 / 20 + 0.5) # 15%
m = int(sum(sorted(a)[t:n - t]) / (n - t * 2) + 0.5) # 위, 아래에서 15%를 제외한 평균
print(m)