입력으로 들어온 값을 $점수/M*100$으로 고친 후 해당 값들의 평균을 출력하는 문제이다.
사실 주의사항 까지는 아니지만, 입력 중간에 연산하는 것보다 모든 값들을 누적 후 마지막에 딱 한 번만 연산을 진행하는 것이 더 효율적인 코드가 된다. → 분배법칙
// 이 코드도 정답이지만
// 나누고 곱하는 과정이 n번만큼 일어난다. -> 비효율적
for(int i = 0; i < n; i++)
{
avg += a[i] / (double)m * 100;
}
// 아래의 코드가 더 효율적이다.
// 마지막에 한 번만 나누고 곱하면 되기 때문이다.
avg = sum / (double)m * 100 / n; // sum은 누적값
// 아래의 코드는 dev c++환경에서 동작됩니다.
// visual studio에서는 bit/stdc++.h가 기본적으로 없기 때문에
// 정삭적인 작동이 되지 않을 수 있습니다.
#include <bits/stdc++.h>
using namespace std;
int n, m = INT_MIN, a[1004], sum;
double avg;
int main()
{
ios::sync_with_stdio(NULL); cin.tie(NULL); cout.tie(NULL);
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
sum += a[i];
m = max(m, a[i]);
}
avg = sum / (double)m * 100 / n;
cout << avg;
return 0;
}
처음에 문제 조건 그대로 구현하다보니 분배법칙까지는 생각이 닿지는 못했는데, 다른 사람들의 블로그를 보니 마지막에 한 번만 연산을 하는 걸 보고 분배법칙을 깨달았다.
코딩테스트 뿐만 아니라 실무에서도 효율적인 코드를 위해 자주 써먹을 방법이라고 생각한다.
추가적으로 누적합을 구할 때 std::accumulate알고리즘을 사용하는 것도 나쁘지 않을 것 같다.
vector<int> v{1, 2, 3, 4, 5};
int sum;
// 세 번째 인자는 시작값
sum = accumulate(v.begin(), v.end(), 0); // 15