T'SPACE

다채로운 에디터들의 이야기

컴퓨터공학/알고리즘

[백준, C++] 2108번: 통계학

Tonny Kang 2024. 1. 1. 23:15
반응형

실패->성공함 ㅎㅎ

문제

수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.

728x90

입력

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

 

https://www.acmicpc.net/problem/2108

 

2108번: 통계학

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

www.acmicpc.net

출력

첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.

둘째 줄에는 중앙값을 출력한다.

셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.

넷째 줄에는 범위를 출력한다.

 

#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <cmath>
using namespace std;

void Average(vector<int>& nums, int size) {
	int average=0;
	for (int i = 0; i < size; i++) {
		average+=nums[i];
	}
	average = round((float)average  / size); //round 함수를 써야 음수에도 제대로 반올림됨
	cout << average << endl;
}

void Mean(vector<int>& nums, int size) {
	int mid= size / 2 ;
	if (size % 2 == 1) {
		cout << nums[mid] << endl;
	}
	else {
		int first = nums[mid - 1];
		first += nums[mid];
		first = first / 2;
		cout << first << endl;
	}
}

int appearance[8001] = { 0, };//각 숫자가 몇번 등장하는지 -4000~4000 의 배열

void Frequent(vector<int>& nums, int size) {	
	int is_second = 0; //두번째로 등장한건지 알려주는 플래그
	int  most = -9999;
	int second = 0;
	for (int i = 0; i < 8001; i++) {
		if (appearance[i] == most) {
			if (is_second) {//두번째로 등장한거면 저장
				second = i - 4000;
				is_second = 0;
			}
		}
		if (appearance[i] > most) {
			most = appearance[i];
			is_second = 1;
			second = i-4000;//두번째로 등장한거 아니고 유일한 최다빈출이면 저장해야함
		}
	}
	cout << second << endl;
}

void Difference(vector<int>& nums, int size) {
	int diff =  nums[size-1]-nums[0];
	cout << diff << endl;
}

int main() {
	int T;
	cin >> T;
	vector<int> nums(T);
	int temp;
	for (int i = 0; i < T; i++) {
		cin >> temp;
		nums[i]=temp;
		appearance[temp + 4000]++;//빈도 배열에 저장해줌
	}
	sort(nums.begin(), nums.end());
	Average(nums, T);
	Mean(nums, T);
	Frequent(nums, T);
	Difference(nums, T);
	cin >> T;
}

 

여기서 어려운 것은 최빈값을 찾을 때
빈도수가 같으면

두번째로 작은 수를 출력해라는게 어려웠다

 

그래서 is_second 라는 플래그로
두번째로 작은 수임을 확인하는 방식으로 해결할 수 있었다

 

그리고 반올림을 할 때 음수를 반올림 하는데 어려움을 겪어 

직접 구현하기 보다

<cmath> 라이브러리를 통해 

round() 함수를 활용해 해결 할 수 있었다

 

<[백준,C++] 1966번: 프린터 큐>

https://tonnykang.tistory.com/11

 

[백준,C++] 1966번: 프린터 큐

https://www.acmicpc.net/problem/1966 1966번: 프린터 큐 여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다

tonnykang.tistory.com

 

반응형