궤도

[백준] 2108번 : 통계학 본문

💻 현생/⛓ 알고리즘

[백준] 2108번 : 통계학

영이오 2020. 10. 15. 22:30

문제

 


풀이

 

요구하는 것이 많지만, 이 중에서 까다로운건 최빈값 구하기 뿐이다. 입력을 받으면서 모든 배열의 합도 구해놓고, 최댓값과 최솟값도 구해놓는다. 그리고 해당 숫자의 등장 횟수도 count 배열을 갱신하며 기록해준다. 중요한건 입력으로 음수가 들어오기도 한다는 것이다. 범위가 -4,000~4,000 이니까 8,000 크기의 배열을 선언하고 입력으로 들어온 값에 4,000을 더한 인덱스를 갱신하면 된다. -4,000~4,000의 범위가 0~8,000으로 변하는 셈이다.

 

입력을 다 받았으면 중앙값을 구하기 위해 정렬한다. 그리고 count 배열을 돌며 최빈값을 체크한다. 해당 최빈값이 유일하다면 바로 출력하면 되지만, 유일하지 않다면 배열을 다시 돌며 최빈값 중 두 번째로 작은 값을 출력한다. 최빈값 중 제일 작은 값이 무엇인지 알고 있으니 그 다음 인덱스부터 돌면 된다.

 

소수점을 고정하기 위해 cout.precision(n)을 사용해왔다. 근데 이게 반올림을 해준다고도 한다. 그럼 그냥 지금까지 구한 값들을 편하게 출력하면 된다.


소스코드

 

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

int main() {
	int N, count[8001] = { 0, }, max = -4001, min = 4001, i;
	double sum = 0.0;
	bool isOne;

	cin >> N;
	int* arr = new int[N];
	for (i = 0; i < N; i++) {
		cin >> arr[i];
		sum += arr[i]; //평균용 합 구하기
		if (arr[i] > max) //최댓값 갱신
			max = arr[i];
		if (arr[i] < min) //최솟값 갱신
			min = arr[i];
		count[arr[i] + 4000]++; //음수도 저장하려고 4000 더한 값에 ++ 해줌
	}
	sort(arr, arr + N); //중앙값용 정렬
	int mode_num, mode_count = 0; //최빈값용 변수
	for (i = 0; i < 8001; i++) {
		if (count[i] == mode_count) //유일한 최빈값인지 체크
			isOne = false;
		else if (count[i] > mode_count) {
			mode_count = count[i];
			mode_num = i - 4000; //원래 4000 더해서 받았으니까 4000 뺌. 만약 유일한 최빈값이면 얠 바로 출력
			isOne = true;
		}
	}
	if (!isOne) { //최빈값이 유일하지 않다면
		for (i = mode_num + 4001; i < 8001; i++) { //받아놓은 mode_num이 첫번째 최빈값일테니까 그 다음부터 체크하면 됨
			if (count[i] == mode_count) {
				mode_num = i - 4000;
				break;
			}
		}
	}
	cout << fixed;
	cout.precision(0); //이게 반올림도 해준다고 함
	cout << sum / N << '\n' << arr[N / 2] << '\n' << mode_num << '\n' << max - min << '\n';
}
Comments