다디와 괴발개발

백준 1546번: 평균 본문

알고리즘/C&C++

백준 1546번: 평균

아임다디 2021. 8. 12. 16:36

문제 링크 : https://www.acmicpc.net/problem/1546

 

1546번: 평균

첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보

www.acmicpc.net

각 점수를 최고점에 맞춰서 재구성하여 새 평균을 내는 문제이다.

문제 자체는 간단하지만 정리하고 싶은 개념이 있어 포스팅하였다!

1. c++ 빠른 입출력

2. c++ 배열 동적으로 할당하기

3. setprecision 함수


1. C++ 빠른 입출력

c++의 cin과 cout은 scanf, printf에 비해 속도가 매우 느리다고 한다. 입출력의 개수가 적을 경우에는 그냥 사용해도 상관없지만, 알고리즘 문제를 풀다보면 데이터의 개수가 많을 때에는 입출력을 가속해야만 시간초과가 되지 않는 경우가 꽤 있다.

ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

 위의 코드를 main문 최상단에 적어주면 된다. 

또한, endl 역시 속도가 느리기 때문에 대신 \n 을 사용하는 것을 권장한다.

 

※ 빠른 입출력 코드 사용시 주의점

  1. 빠른 입출력 사용시 scanf, printf 사용 불가
  2. 싱글 쓰레드 환경에서만 사용 가능

이래도 시간초과가 나면 조용히 지워주고 scanf와 printf를 사용해주도록 하자

 


2. c++ 동적으로 배열 할당하기

문제에서 젤 첫 번째 줄에 주어지는 개수에 따라 입력해야 할 배열 길이가 달라지도록 구현하고 싶어 동적으로 배열을 할당하는 방법을 찾아보았다.

 

double array[num]; 으로 선언하려하면 num이 상수가 아니므로 불가하다.

double array[num]; 으로 선언하려 할 때 나오는 에러

이럴땐 동적 할당을 이용하면 쉽게 해결된다.

동적 배열 할당의 핵심 요소는 new[], delete[] 연산자를 사용하는 것 이다.

int num = 0;
cin >> num;
double* array = new double[num]; //동적 배열 할당

delete[] array; //배열이기 때문에 전체를 해제하기 위해 []를 붙여줘야 한다

이번 문제에서는 double 형을 사용하기때문에 double 배열을 선언해주었다. 상황에 맞는 형을 사용하면 된다.

동적 할당 방법을 이용했기 때문에 num 값이 상수가 아니더라도 정상적으로 작동하는 것을 확인할 수 있다.


3. setprecision 함수

이번 문제에서는 소수점 출력때문에 [스페셜 저지] 로 채점된다.

이번 문제의 경우 실제 정답과 출력값의 절대오차 또는 상대 오차가 10^(-2) 이하이면 정답으로 인정된다.

 

setprecision 함수를 사용하기 위해서는 헤더파일 <iomanip> 가 필요하다.

매개변수에 자릿수를 10으로 지정하였을 경우 정수부분 + 소수부분 합하여 10자리만 출력하도록 한다.

#include <iomanip>

cout << setprecision(10) << avg;

setprecision(10) 함수 사용 전과 후 출력 비교

※ fixed 의 유무

fixed 가 있는 경우 : 소수분만을 기준으로 입력한 자릿수만큼 반올림하여 출력

fiexed 가 없는 경우 : 정수부 + 소수부 기준으로 입력한 자릿수만큼 반올림하여 출력

cout << setprecision(10) << avg; // 정수부분 + 소수부분 포함하여 총 10자리가 되도록 출력
//결과 66.66666667

cout << fixed << setprecision(10) << avg; // 소수부분이 10자리 나오도록 출력
//결과 66.6666666667

최종 완성 코드

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

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int num, max = 0;
    double sum = 0, avg = 0;
    cin >> num;
    double* array = new  double[num]; //c++ 배열 동적 할당

    for (int i = 0; i < num; i++) {
        cin >> array[i];
        if (array[i] > max) max = array[i];
    }

    for (int i = 0; i < num; i++) {
        array[i] = array[i] * 100;
        array[i] /= (double)max; //max가 정수이므로 형변환
        sum += array[i];
    }
    avg = (double)sum / num;
    cout << setprecision(10); //소수점을 더 출력하기 위해 사용
    //헤더파일 iomanip 를 사용해야 함수 사용 가능
    cout << avg;

    delete[] array; //해제
    return 0;
}

배열을 첫줄에 입력받은 num을 이용하여 num만큼 배열을 할당해주고

동시에 최대값 max 와 비교하여 입력값이 max보다 클 때 max를 갱신해준다.

 

배열입력이 다 되었으면 새로운 수식인 점수/max*100 으로 값을 갱신해준 후 합계에 더해준다.

평균을 구하기 위해 sum / num 을 한 후 setprecision을 이용하여 출력 형식에 맞게 평균값을 출력해준다.