공부/Code Cata
과일장수
동그래님
2025. 1. 7. 16:04
*초기 작성 코드
더보기
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
void check_apple(unordered_map<int, int>& List, int k, const vector<int>& score)
{
for (int i = 1; i <= k; ++i)
{
int k_cnt = count(score.begin(), score.end(), i);
List[i] = k_cnt;
}
}
int solution(int k, int m, vector<int> score)
{
unordered_map<int, int> apple_cnt;
int result = 0;
// score 점수별로 사과가 몇 개 있는지 정리
check_apple(apple_cnt, k, score);
// k점수부터 1점수까지 m개씩 포장해서 점수 계산
for (int i = k; i >= 1; --i)
{
// 만약 개수가 m보다 작다면 밑에 점수 개수에 저장
if (apple_cnt[i] < m)
{
apple_cnt[i - 1] += apple_cnt[i];
continue;
}
// m으로 나눈 몫 * 점수를 result에 더해 저장
result += (apple_cnt[i] / m) * i * m;
// 나머지를 밑에 점수 개수에 저장
apple_cnt[i - 1] += apple_cnt[i] % m;
}
return result;
}
- unordered_map을 사용해서 score의 점수 별로 사과가 몇 개 있는지 먼저 정리한 후 이 리스트를 가지고 최대 이익을 계산하는 방향으로 코드를 작성했다.
- 문제에서 score의 크기가 1,000,000까지 아주 많은 경우가 생길 수 있는데, 현재 코드에서 count함수를 사용해 score 크기 만큼 루프를 k번이나 돌아야해서 비효율적이라는 생각이 들었다.
- 루프를 최소화 하는 방향으로 다시 코드를 작성하려 고민했다.
*수정 코드
더보기
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int solution(int k, int m, vector<int> score)
{
int result = 0;
// score 내림차순으로 정렬
sort(score.begin(), score.end(), greater<>());
// i는 m씩 증가, i + m이 score.size를 초과하기 전까지 반복
for(int i = 0; i + m <= score.size(); i += m)
{
// 내림차순 정렬했기 때문에 m번째 요소가 박스에 들어갈 최소 점수
int min_score = score[i + m - 1];
// 최소 점수 * 개수를 저장
result += min_score * m;
}
return result;
}
- 우선 score를 내림차순으로 정렬해주었다.
- 정렬이 되었기 때문에, m번째 요소가 한 박스의 최소 점수가 되고 이를 m으로 다시 곱해 그 박스의 이익을 계산하였다.
- 별도의 추가 컨테이너도 사용하지 않았고, 1개의 루프로 해결할 수 있어서 시간 또한 세이브되었다고 보여진다.
요즘 문제를 풀면서 더 효율적인 방법이 없을지 계속 생각하다 보니, 이것 저것 불필요한 컨테이너를 사용하게 되면서 오히려 과정이 더 많아져 코드가 복잡해지고 비효율적인 결과가 나오는 듯하다..:(