티스토리 뷰

728x90
반응형

백준 온라인 저지(BOJ) 2108번 통계학
https://www.acmicpc.net/problem/2108

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net

* 사용언어 : C언어, C++
 

1. 문제

N개의 수를 대표하는 기본 통계값을 순서대로 출력
(산술평균, 중앙값, 최빈값, 범위)

 

2. 풀이

산술평균을 구하기 위해 round 함수를 구현했습니다.
round 함수는 양수일 경우 +0.5를 한 뒤 int로 형변환(내림)하고, 음수일 경우 -0.5를 한 뒤 int로 형변환 합니다.
 
만약 제출했을 때 2%에서 '틀렸습니다'가 나온다면 음수 처리를 제대로 못 해서 가능성이 높습니다.
(처음에 +0.5만 했을 때 계속 2%에서 틀리다가, 음수인 경우 -0.5한 이후 2%를 넘어 통과했습니다)
 
 
최빈값의 경우 -4,000 ~ 4,000의 숫자들 중 가장 많이 등장한 숫자를 확인해야 합니다.
이를 간편하게 처리하기 위해 8,001크기의 배열을 선언한 뒤
숫자에 + 4000을 해서 각각의 숫자가 배열의 index 값에 대응되도록 했습니다.
 
문제 조건에 따라 최빈값이 여러 개인 경우 두 번째로 작은 값을 출력하면 되기 때문에
단순하게 최빈값에 해당하는 숫자의 개수(modeCnt)가 2이상인 경우 2로 초기화했습니다.
 
그리고 저장해둔 cnt 배열을 작은 수부터 순차적으로 탐색한 뒤
2번째 숫자를 최빈값(mode)로 출력하게 했습니다. (1개인 경우 1번째)
 
이후 풀이는 아래 코드로 대체하겠습니다.
 

3. 코드

#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
/*
2108_통계학
5052KB	116ms
*/
#include <cstdio>

const int LM = 500000;
const int NBASE = 4000;
const int NLM = NBASE * 2 + 1;
int N, n, a[LM], t[LM], cnt[NLM];
double sum;

int round(double v) {
	if (v > 0) v += 0.5;
	else v -= 0.5;
	return (int)v;
}

void mSort(int s, int e) {
	if (s >= e) return;

	int m = (s + e) / 2;
	mSort(s, m);
	mSort(m + 1, e);

	int i = s, j = m + 1, k = s;
	while (i <= m && j <= e) {
		if (a[i] < a[j]) t[k++] = a[i++];
		else t[k++] = a[j++];
	}

	while (i <= m) t[k++] = a[i++];
	while (j <= e) t[k++] = a[j++];

	for (i = s; i <= e; ++i) a[i] = t[i];
}

int main() {
#ifdef _WIN32
	freopen("input.txt", "r", stdin);
#endif // _WIN32
	scanf("%d", &N);
	for (int i = 0; i < N; ++i) {
		scanf("%d", &n);
		a[i] = n;
		sum += n;
		cnt[NBASE + n] += 1;
	}

	int modeCnt = 0, maxCnt = -1;
	for (int i = 0; i < NLM; ++i) {
		if (cnt[i] > maxCnt) {
			maxCnt = cnt[i];
			modeCnt = 1;
		}
		else if (cnt[i] == maxCnt) ++modeCnt;
	}
	if (modeCnt > 1) modeCnt = 2;

	int mode;
	for (int i = 0; i < NLM; ++i) {
		if (cnt[i] == maxCnt) {
			if (modeCnt > 1) {
				--modeCnt;
				continue;
			}
			if (modeCnt == 1) {
				mode = i - NBASE;
				break;
			}
		}
	}

	mSort(0, N - 1);

	printf("%d\n", round(sum / N));
	printf("%d\n", a[N / 2]);
	printf("%d\n", mode);
	printf("%d\n", a[N - 1] - a[0]);

	return 0;
}

 

728x90
반응형
댓글