체조나 다이빙 등의 경기에서 일부 심판이 자기가 좋아하는 선수에게 높은 점수를,
싫어하는 선수에게 낮은 점수를 주는 경우가 종종 있었다. 따라서 심판들이 주는
점수의 평균점수를 선수에게 주게 되면 공정하지 않은 경우가 생길 수 있다.
이를 방지하기 위하여 절사평균이나 보정평균을 사용한다.
예를 들어 심사위원 일곱 명이 다음과 같이 점수를 주었다고 하자.
9.3, 9.5, 9.6, 9.8, 9.1, 5.0, 9.3
전체의 합이 61.6이 되므로 평균은 8.8이 된다.
이 평균점수는 한 심판이 다른 심판에 비하여 아주 낮은 점수인 5.0을 주어서 나온 결과로,
선수는 매우 불공정하다고 느낄 것이다.
위의 점수를 작은데서 큰 순서로 정렬하면 5.0, 9.1, 9.3, 9.3, 9.5, 9.6, 9.8 이 된다.
이때 절사평균(7, 2)는 정렬된 전체 점수 일곱 개 중 양쪽 끝에서 두 개씩을 제외하고 난
9.3, 9.3, 9.5의 평균인 9.37이 된다(소수점이하 셋째 자리에서 반올림).
N개의 점수와 양쪽에서 제외하는 개수 k 값이 주어졌을 때 절사평균(N, K)을 계산하는
프로그램을 작성하시오.
입력 출력
7 2 9.37
9.3
9.5
9.6
9.8
9.1
5.0
9.3
아래에서는 점수가 0점부터 100점까지의 정수라고 가정하고 푼 것입니다.
보통 소수점 1자리, 2자리까지 있는 점수의 경우는 10을 곱하거나, 100을 곱하여
간단히 정수로 만들어 줄수 있겠습니다.
#include <stdio.h>
int main() {
FILE *in=fopen("input.txt", "r");
FILE *out=fopen("output.txt", "w");
int so[100000], a[1000]={0,};
int i, j, k , n ;
int sum=0, sum1=0, sum2=0;
double ave;
// 갯수 n과 제외할 갯수 k를 입력받는다.
// k는 1이상이라고 가정한다. (0이 아니다)
fscanf(in,"%d %d", &n ,&k);
// 질문1: 점수는 정수로 입력이 되는 것인가?
// 점수의 범위는 어떻게 되는가?
for(i=0;i<n;i+=1) {
fscanf(in, "%d", &so[i]);
sum+=so[i];
}
// 점수가 0점부터 100점까지라고 가정하고 푼 것입니다.
// 점수자체를 배열의 인덱스로 사용할려면 모두 101칸이 필요합니다.
// 이렇게 모든 값을 0으로 초기화를 하지 않아도 되지만
// 문제의 배경을 제대로 모르기 때문에 이렇게 써봅니다.
for(i=0;i<101;i+=1) {
a[i]=0;
}
// 카운팅 소트를 하기 위해서 갯수를 세어 줍니다.
for(i=0;i<n;i+=1) {
a[so[i]]+=1;
}
// 전체 수를 정렬하지 않고서 바로 a[]배열에 들어 있는 갯수만 가지고
// 위에서 구한 sum에서 앞부분의 k명의 점수와, 뒷부분의 k명의 점수를 빼 줍니다.
// 먼저 앞부분입니다. sum1에 그 합을 구합니다.
// i는 점수 입니다. 0점 부터 출발해서 각 점수의 명수를 더해서 k명이 될 때 까지 진행합니다.
i=0;
j=0;
while(j+a[i]<=k) {
sum1+=i*a[i];
j+=a[i];
i+=1;
}
// while문을 탈출했습니다.
// j+a[i]가 k보다 큽니다.
// 하지만 j는 k 보다 작을 수 있습니다.
if(j<k) {
sum1+=i*(k-j);
}
// 뒷부분입니다. sum2에 그 합을 구합니다.
// i는 점수 입니다. 100점 부터 출발해서 각 점수의 명수를 더해서 k명이 될때 까지 아래로 내려갑니다.
i=100;
j=0;
while(j+a[i]<=k) {
sum2+=i*a[i];
j+=a[i];
i-=1;
}
// while문을 탈출했습니다.
// j+a[i]가 k 보다 큽니다.
// 하지만 j는 k보다 작을 수 있습니다.
if(j<k) {
sum2+=i*(k-j);
}
// 다 구했습니다.
// sum에는 전체합이 들어 있습니다.
// sum1에는 낮은 점수 k명의 합이 들어 있습니다.
// sum2에는 높은 점수 k명의 합이 들어 있습니다.
ave=(double)(sum-sum1-sum2)/(n-k*2);
fprintf(out,"%.2f",ave);
return 0;
}
'c·c++ > c 프로그래밍' 카테고리의 다른 글
단어세기 (0) | 2013.08.21 |
---|---|
c언어로 모터 제어하기 (0) | 2013.08.21 |
ipconfig내용 캡쳐해서 가져오기 (0) | 2013.08.21 |
큰수의 나눗셈 - 0x100000000 진법 (0) | 2013.08.02 |
큰수의 나눗셈 - 만진법 (0) | 2013.07.31 |