※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 6986번 문제인 절사평균이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/6986
6986번: 절사평균
첫째 줄에 절사평균(N, K)를, 둘째 줄에 보정평균(N, K)를 각각 소수점이하 셋째 자리에서 반올림하여 둘째 자리까지 출력한다. 예를 들어 결과값이 9.667인 경우 9.67로, 5인 경우 5.00으로, 5.5인 경우
www.acmicpc.net
지문에는 예시만 주어져있어 설명을 보충하면 절사평균(N,K)는 주어진 N개의 원소 중 가장 작은 K개의 원소와 가장 큰 K개의 원소를 제외한 (N-2*K)개의 원소의 평균을 의미하고, 보정평균(N,K)는 주어진 N개의 원소 중 가장 작은 K개의 원소를 K+1번째의 원소와 같은 값으로 취급하고 가장 큰 K개의 원소를 N-K번째의 원소와 같은 값으로 취급해 구한 N개의 원소의 평균을 의미한다.
나눗셈의 실수 오차에 주의하자. 실수 오차를 피하기 위해, 구하는 식을 정수의 나눗셈으로 바꿔(분모와 분자에 10을 적절히 곱하자) 한 자리 한 자리 자릿수를 구해나가는 방식의 나눗셈을 직접 구현하여 소수점 아래 세번째 자리를 직접 확인하는 식으로 구현해 문제를 해결하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
typedef long double ld;
int N, K;
int arr[100000];
int total1, total2;
int ans1, ans2;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> K;
for (int i = 0; i < N; i++) {
string s; cin >> s;
if (s.length() == 4) arr[i] = 100;
else arr[i] = ((int)s[0] - '0') * 10 + (int)s[2] - '0';
}
sort(arr, arr + N);
for (int i = K; i < N - K; i++)total1 += arr[i];
total2 = total1;
for (int i = 0; i < K; i++) total2 += arr[K];
for (int i = N - K; i < N; i++) total2 += arr[N - K - 1];
ans1 += total1 / (N - 2 * K);
total1 = (total1 % (N - 2 * K)) * 10, ans1 *= 10;
ans1 += total1 / (N - 2 * K);
total1 = (total1 % (N - 2 * K)) * 10;
if (total1 / (N - 2 * K) > 4) ans1++;
cout << ans1 / 100 << '.';
ans1 %= 100;
cout << ans1 / 10;
ans1 %= 10;
cout << ans1 << ' ';
ans2 += total2 / N;
total2 = (total2 % N) * 10, ans2 *= 10;
ans2 += total2 / N;
total2 = (total2 % N) * 10;
if (total2 / N > 4) ans2++;
cout << ans2 / 100 << '.';
ans2 %= 100;
cout << ans2 / 10;
ans2 %= 10;
cout << ans2;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 2615 // C++] 오목 (1) | 2023.03.08 |
---|---|
[BOJ 2617 // C++] 구슬 찾기 (0) | 2023.03.08 |
[BOJ 27622 // C++] Suspicious Event (0) | 2023.03.08 |
[BOJ 9913 // C++] Max (0) | 2023.03.07 |
[BOJ 6988 // C++] 타일 밟기 (0) | 2023.03.07 |