본문 바로가기
백준

[2108] 통계학

by kmyobin 2022. 7. 17.

구해야 할 것은 총 4가지이다

1. 산술평균 : (N개의 수들의 합 / N)을 소수 첫째 자리에서 반올림한 값

2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 때 중앙에 위치하는 값

3. 최빈값 : N개의 수들 중 가장 많이 나타난 값

4. 범위 : N개의 수들 중 최댓값 - 최솟값

 

입력을 어떻게 받을까 고민했다

최빈값을 위해 num의 빈도수를 나타내는 cnt 변수를 사용하였다

그리하여 num, cnt 두 변수를 담는 구조체 배열을 선언해주었다

 

입력을 받을 때는 이미 입력됐었던 수인지 일단 따져본다

입력된 적이 있던 수라면 ? -> cnt만 1 증가

새로 입력된 수라면 ? -> num 대입, cnt 1 증가

 

1. 산술평균

for문을 돌리면서 입력을 받을 때 sum을 더해준다

그리고 그것을 N으로 나눠주는데, 소수 첫째 자리에서 반올림해야 하므로 floor함수를 이용하였다.

floor(구하려는 값 + 0.5)를 하면 반올림한 값이 된다

 

 

2. 중앙값

일단 sort함수를 이용하여 오름차순으로 정렬한다

그리고 middle 변수를 선언해준다

middle은 N/2로 설정해준다

정렬은 num을 기준으로 오름차순으로 정렬돼있으니,

middle을 1씩 감소시키면서 중앙값을 찾아낸다

그리고 이 때 4번(범위)을 구하기 위해 num으로 정렬돼있는 지금의 m배열에서 최댓값, 최솟값을 미리 구한다

 

 

3. 최빈값

이번에는 빈도수를 기준으로 내림차순으로 정렬한다

최빈값이 2개 이상이면 2번재로 작은 값을 출력하기 위해 m[1].num,

최빈값이 1개이면 m[0].num을 출력한다

 

 

4. 범위

2번에서 구했던 최댓값에서 최솟값을 빼면 된다

 

 

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

typedef struct memo {
	int num;
	int cnt;
}memo;

memo m[500001];
double result;
int N;

bool cmp1(memo a, memo b) {
	return a.num < b.num;
}

bool cmp2(memo a, memo b) {
	if (a.cnt == b.cnt) {
		a.num < b.num;
	}
	return a.cnt > b.cnt;
}

// 반올림 하는 법 floor(X+0.5)

// 산술평균 : N개의 수들의 합 / N
// 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
// 최빈값 : N개의 수들 중 가장 많이 나타나는 값
// 범위 : 최댓값 - 최솟값

int main() {
	cin >> N;

	int k = 0;

	for (int i = 0; i < N; i++){
		int x;
		bool isit = false;
		cin >> x;
		result += x; // 산술평균
		for (int j = 0; j < k; j++) {
			if (x == m[j].num) { // 이미 입력됐었던 수라면
				m[j].cnt++;
				isit = true;
				break;
			}
		}
		if (isit == true) {} // 이미 입력됐었던 수라면 pass
		else { // 새로 입력된 수라면
			m[k].num = x;
			m[k].cnt++;
			k++;
		}
	}

	// 1. 산술평균
	cout << int(floor(result / double(N) + 0.5)) << endl;
	 

	// 2. 중앙값
	sort(m, m + k, cmp1);

	// 최댓값, 최솟값 미리 구함
	int maximum = m[k - 1].num;
	int minimum = m[0].num;	
	
	
	int middle = N / 2;
	bool isit = false;
	for (int i = 0; i < k; i++) {
		for (int j = 0; j < m[i].cnt; j++) {
			if (middle == 0) {
				cout << m[i].num << endl;
				isit = true;
				break;
			}
			middle--;
		}
		if (isit == true) { break; }
	}



	// 3. 최빈값
	sort(m, m + k, cmp2);
	if (m[0].cnt == m[1].cnt) { // 최빈값이 두 개 이상이면
		cout << m[1].num << endl; // 두 번째로 작은 값
	}
	else {
		cout << m[0].num << endl;
	}

	// 4. 범위
	cout << maximum - minimum << endl;


}

 

'백준' 카테고리의 다른 글

[18870] 좌표 압축  (0) 2022.07.22
[1181] 단어 정렬  (0) 2022.07.22
[1427] 소트인사이드  (0) 2022.07.17
[10989] 수 정렬하기 3  (0) 2022.07.08
[2231] 분해합  (0) 2022.07.08

댓글