[ 백준 ] 6986 / 절사평균

金弘均·2021년 9월 14일
0

Baekjoon Online Judge

목록 보기
22/228
post-thumbnail
post-custom-banner

# Appreciation

/*
 * Problem :: 6986 / 절사평균
 *
 * Kind :: Simulation
 *
 * Insight
 * - 문제에서 하란대로 했는데 틀렸다
 *   질문을 살펴보니 부동소수점 오차때문이라고 한다
 *   + https://www.acmicpc.net/board/view/49789
 *     그냥 round 등의 함수나 %.2lf 등을 이용하여 반올림을 했을 시
 *     일반적인 반올림이 아닌 Round-to-nearest-even 으로 반올림을 해서 그렇습니다
 *     라고 한다
 *     # Round-to-neareset-even
 *       해석 그대로 가장 가까운 짝수로 반올림을 한다는 것인데 이러면
 *           우리가 생각하는 반올림 / 위에서 말한 반올림
 *       1.5         2        /       2
 *       2.5         3        /       2
 *       3.5         4        /       4
 *       4.5         5        /       4
 *       5.5         6        /       6
 *       6.5         7        /       6
 *       ...
 *       -> 우리가 생각하는 반올림 = 사사오입
 *          위에서 말한 반올림 = 오사오입
 *          자료를 찾아보 오사오입이 좀더 덜 편향된다는 데
 *          위의 결과를 보니 그 이유를 짐작할 수 있었다
 *
 * - 여튼 그냥 %.2f 등으로는 안된다는 건데...
 *   근데 C++ 공식 reference 를 살펴보니
 *   round 는 사사오입이네???
 *   https://en.cppreference.com/w/cpp/numeric/math/round
 *   + round(1.5)  # 2
 *     round(2.5)  # 3
 *     round(3.5)  # 4
 *     ...
 *     # 그렇다면 구한 값에서
 *       100 을 곱하고 round 함수를 적용한 후 다시 100 으로 나누면
 *       사사오입의 소수점 둘째 자리까지 정확하게 구할 수 있겠다!
 *
 * Point
 * - 부동소수점 오차 싫어...
 *
 * - 정수형으로 바꿔서 계산할 수도 있긴 하다
 *   + 정신건강을 위해선 이 방법이 바람직 하지만
 *     부동소수점 다시 공부하는 셈쳤다
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <algorithm>
#include <numeric>
#include <cmath>

using namespace std;

#define endl '\n'

// Set up : Global Variables
/* None */


// Set up : Functions Declaration
/* None */


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int N, K;
    cin >> N >> K;
    double A[N];
    for (int i=0; i<N; i++)
        cin >> A[i];

    // Process
    sort(A, A+N);
    /* trimmed mean: 절사평균 */
    double tm = accumulate(A+K, A+N-K, (double)0) / (N-2*K);
    fill(A, A+K, A[K]);
    fill(A+N-K, A+N, A[N-K-1]);
    /* adjusted mean: 보정평균 */
    double am = accumulate(A, A+N, (double)0) / N;

    // Control : Output
    printf("%.2f\n", round(tm*100)/100);
    printf("%.2f\n", round(am*100)/100);
}

// Helper Functions
/* None */
profile
이런 미친 게임을 봤나! - 옥냥이
post-custom-banner

0개의 댓글