5. 야근 지수 알고리즘
Algorithm - Level 3
- 풀이
1. 원소 중 최대값에 1을 빼는 행동을 n번 만큼 반복하면 된다.
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 38 39 40 41 42 43 44 45 46 47 48 49 50 | #include <string> #include <vector> #include <algorithm> #include <numeric> using namespace std; long long calculate(vector<int> a){ long long answer = 0; for(int i=0; i<a.size(); ++i) answer += (a[i]*a[i]); return answer; } long long solution(int n, vector<int> works) { long long answer = 0; sort(works.rbegin(), works.rend()); if(works[0] == 0) return 0; else if(accumulate(works.begin(), works.end(), 0) < n) return 0; else if(works[0]-works[1]>=n){ works[0]-=n; return calculate(works); } else{ for(int i=1; i<works.size(); ++i){ while(works[i-1]!=works[i]){ for(int j=0; j<i; ++j){ if(works[j]!=0){ works[j]--; if(--n==0) return calculate(works); } } } } if(works[0]>0){ int idx=0; while(n>0){ if(works[idx]>0){ works[idx++]--; n--; } } } } return calculate(works); } | cs |
위 풀이 방법은 <1>에서 말한 방법을 푼 방식으로 효율성을 위해 내림차순으로 정렬 후
1. 맨 처음 원소가 0이라면, 결과는 0이다.
2. 모든 원소의 덧셈이 n보다 이하라면 결과는 0이다.
3. 첫 원소와 두 번째 원소의 차이가 n 이상이라면 첫 원소에 n을 뺀 후 누적을 계산하면 된다.
4. 모든 원소를 같게한 후 남은 n만큼 번갈아가며 감소한다.
여기서 내가 원하는 함수(최대값을 찾는)를 못찾았었는데, 다른 사람의 풀이를 보니 내가 구현한 코드가 이미 함수로 구현되어 있었다. 그것을 이용하여 풀어보면,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <string> #include <vector> #include <iostream> #include <algorithm> using namespace std; long long solution(int n, vector<int> works){ long long answer = 0; while(n!=0){ *max_element(works.begin(), works.end()) -= 1; n--; } for(int i=0; i<works.size(); ++i) answer += (works[i]*works[i]); return answer; } | cs |
다음과 같이 간략화된다.
max_element는 최대값 원소를 반환하는 함수로, 여기에 *를 붙여 해당 위치에 1을 감산하여 반복할 수 있게 된다.
'Study > Algorithm' 카테고리의 다른 글
[백준][I/O] 그대로 출력하기 (0) | 2019.01.29 |
---|---|
[Level 3] 6. 줄 서는 방법 (0) | 2018.08.15 |
[Level 3] 4. 멀리 뛰기 (0) | 2018.08.09 |
[Level 3] 3. 거스름돈 경우의 수 (0) | 2018.08.07 |
[Level 3] 2. Palindrome (0) | 2018.08.06 |