https://www.acmicpc.net/problem/2108
처음 풀었을 때 최빈 값에 대한 알고리즘이 틀렸었다.
왜 그런가 하니 두번째로 작은 값을 잘못 구한 것이였다.
최빈 값을 구할 때 만약 나온 횟수가 같으면 두번째로 작은 수를 출력하라고 하였으므로, not_first라는 bool형 플래그값을 줘서 만약 나온 횟수가 같다면 두번째로 작은 값이 저장되도록 한다.
또한 문제 풀이 과정 중 모든 테스트 케이스가 맞는데도 틀린 현상이 일어났다.
계속해서 고민과 주변인에게 질문한 결과 float라는 자료형의 문제인 것을 알게 되었다.
평균 값 계산 시 float가 아닌 double을 사용해야한다.
이유는 float과 double의 오차 때문이다. float에 비해 double이 표현할 수 있는 실수의 범위는 더 넓다.
float의 경우 6자리까지 표현할 수 있으며, double의 경우 15자리까지 표현할 수 있다.
이로인해 반올림 연산 시 float을 사용하면, 오차가 생길 수 있어 double을 사용해야한다.
예를들어 123456789.123을 float형 변수와 double형 변수에 넣게 된다면,
float의 경우 123456792.000000이 출력되고, double의 경우 123456789.123000이 출력된다.
자세한 내용은 아래 글 참고
https://hanseongbugi2study.tistory.com/22
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
int counter[8001] = {0,};
int main(){
int N;
cin>>N;
vector<int> arr;
arr.assign(N,0);
double avg = 0;
for(int i = 0;i<N;i++){
int input;
cin>>input;
arr[i] = input;
avg += input;
counter[input+4000] ++;
}
avg /= N; // 산술 평균 연산
sort(arr.begin(),arr.end());
int mid = arr[N/2]; // 중앙 값 연산
int min = 0;
int most = -9999;
bool not_first = false;
for(int i = 0;i<8001; i++){
if(counter[i] == 0) continue;
if(counter[i] == most){
if(not_first){
min = i - 4000;
not_first = false;
}
}
if(counter[i] > most){
most = counter[i];
min = i - 4000;
not_first = true;
}
}
int range = arr[N-1] - arr[0]; // 범위 연산
double average = round(avg);
if(avg < 0.5 && avg>-0.5) average = 0;
cout<<average<<'\n';
cout<<mid<<'\n';
cout<<min<<'\n';
cout<<range<<'\n';
}
'Baekjoon Review' 카테고리의 다른 글
[Bronze 2] 2798번 블랙잭 (0) | 2023.10.12 |
---|---|
[Silver 4] 2164번 카드2 (0) | 2023.10.11 |
[Silver 5] 2751번 수 정렬하기 2 (0) | 2023.10.10 |
[Silver 3] 1966번 프린터 큐 (0) | 2023.10.10 |
[Silver 3] 1929번 소수 구하기 (0) | 2023.10.10 |