티스토리 뷰
![](https://blog.kakaocdn.net/dn/kxVKX/btsCRhdsCuj/JANegJtYNqpJkwObG5EEkk/img.jpg)
백준 온라인 저지(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개의 수를 대표하는 기본 통계값을 순서대로 출력
(산술평균, 중앙값, 최빈값, 범위)
![](https://blog.kakaocdn.net/dn/WyWMm/btsC2z4co7y/xG44u8pmkvRaQHiAXKvlHk/img.png)
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;
}
'개발자 > 문제풀이 (C언어)' 카테고리의 다른 글
[백준/BOJ] 27433번 팩토리얼 2 (C/C++) (0) | 2024.01.06 |
---|---|
[백준/BOJ] 20920번 영단어 암기는 괴로워 (C/C++) (0) | 2024.01.04 |
[백준/BOJ] 26069번 붙임성 좋은 총총이 (C/C++) (0) | 2024.01.01 |
[백준/BOJ] 25192번 인사성 밝은 곰곰이 (C/C++) (0) | 2023.12.27 |
[백준/BOJ] 1037번 약수 (C/C++) (0) | 2023.12.26 |
- Total
- Today
- Yesterday
- 긴 자리 곱셈
- 자료구조
- 쿠프마케팅
- 센터독서클럽
- 독서감상평
- 독서 감상평
- 알고리즘
- AdSendse
- JUNGOL
- 정세현의통찰
- 문현공
- 유연함의힘
- 영화감상평
- 최재천의공부
- 삼성전자
- 동탄에듀센터
- 호암의마지막꿈
- 시대예보
- 긴 자리 덧셈 뺄셈
- 관계가상처가되기전에
- 인간본성불패의법칙
- 정올
- 안전운전특약
- 자동차보험
- 나의첫죽음학수업
- 당신도느리게나이들수있습니다
- 세상을 읽는 새로운 언어 빅데이터
- 나는늘잘해야한다고생각한다
- 동탄에듀센터2
- 여가포인트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |