cosmic developer

[백준알고리즘] 4344. 평균은 넘겠지 - 1차원 배열 (C/C++) 본문

Algorithm

[백준알고리즘] 4344. 평균은 넘겠지 - 1차원 배열 (C/C++)

ti:bot 2020. 3. 8. 03:50

 문제  #4344

대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.


 입력 

첫째 줄에는 테스트 케이스의 개수 C가 주어진다.

둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.


 출력 

각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.


예제 입력

5
5 50 50 70 80 100
7 100 95 90 80 70 60 50
3 70 90 80
3 70 90 81
9 100 99 98 97 96 95 94 93 91


예제 출력1

40.000%
57.143%
33.333%
66.667%
55.556%





문제 접근

① 테스트 케이스의 개수 C 입력받기 ▶ int

② 아래 전 과정(3~7)을 C만큼 반복 ▶ for문

③ 학생 수 N 입력 ▶ int

④ 학생 수 만큼의 원소를 가지는 일차 배열 선언 ▶ 동적 배열 할당

⑤ 점수 N번 입력받아 평균 구하기 ▶ for문

⑥ 평균과 학생 N명의 점수를 각각 비교하여 평균을 넘는 학생의 경우는 카운트 ▶ for문, if문

⑦ (평균을 넘는 학생 수 / 전체 학생 수) 결과 출력



소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
 
int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    int n, num = 0, count;    
    float average;    
    
    cin >> n;
    int *student = new int[num];    
 
    for (int i = 0; i < n; i++) {
        cin >> num;
        average = 0; count = 0;
 
        for (int j = 0; j < num; j++) {
            cin >> student[j];
            average += (float)student[j] / num;
        }
 
        for (int j = 0; j < num; j++if (average < student[j]) count++;
 
        cout.precision(3);
        cout << fixed << round((float)count/num * 100000/ 1000 << "%\n";
    } 
 
    delete[] student;
    return 0;
}
cs



문제점

1. 컴파일 에러 - 헤더 파일 미포함


아래와 같은 오류 메세지를 확인할 수 있다.

HEAP CORRUPTION DETECTED: after Normal block (#189) at 0x0135CB50

CRT detected that the application wrote to memory after end of heap buffer.


이에 대해 검색했을 때 동적 배열로 할당한 메모리의 영역에 대해 잘못 선언한 것이 원인으로, 보통 배열의 크기를 조정하면 해결이 되었다. 하지만 나는 그렇게 해결할 수 없었고그 이유에 대해 한참을 헤맸다. 그러던 중에 우연히 제출란에 제출을 하면 오류 사항을 정확히 알려주는 것을 발견했다... 이 생각을 못했다니 바보같았다.

어쨌든 원인을 아래와 같이 발견했다.


!error: ‘round’ was not declared in this scope


보다시피 이유는 허무했다. 반올림 값을 구하기 위한 round 함수를 사용하기 위한 헤더 파일을 include하지 않았던 것.

아래의 한 줄만 추가했더니 해결할 수 있었다. 역시 꼼꼼히 확인해야 함.


#include <math.h>



2. 런타임 에러 - 동적 배열 선언 위치

이번에는 런타임 에러가 발생했다.

배열을 첫 번째 for문에서 선언하였더니 해당 에러를 해결할 수 있었다.



3. 틀렸습니다 - 자료형

FAQ에서도 확인할 수 있는 만큼 많은 사람들이 겪었던 문제인 것 같다.

평균을 float이 아니라 double로 선언하면 해결된다.




성공

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <math.h>
using namespace std;
 
int main() {
    // 속도 개선
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    int n, num = 0, count;    // 테스트 케이스의 개수; 케이스별 학생의 수; 평균을 넘는 학생 수
    double average;    // 반 평균
    
    cin >> n;
 
    for (int i = 0; i < n; i++) {
        // 각 케이스별 학생의 수를 입력받고, 평균과 평균을 넘는 학생 수를 초기화한다.
        cin >> num;
        average = 0; count = 0;
 
        int *student = new int[num];    // 케이스별 학생 수에 따른 점수 배열
        
        // 학생의 수 만큼 점수를 입력받고 이를 학생 수로 나누어 누적하는 방식으로 평균을 구한다.
        for (int j = 0; j < num; j++) {
            cin >> student[j];
            average += (float)student[j] / num; // 평균이 정수형이면 예외 발생
        }
 
        // 평균을 넘는 점수를 받은 학생 수를 센다.
        for (int j = 0; j < num; j++if (average < student[j]) count++;
 
        cout.precision(3);    // 소수 셋째 자리까지 표현
        cout << fixed << round((double)count/num * 100000/ 1000 << "%\n";    // 반올림
 
        delete[] student;
    } 
 
    return 0;
}
cs