16206번: 롤케이크
오늘은 재현이의 생일이다. 재현이는 친구 N명에게 롤케이크를 1개씩 선물로 받았다. 롤케이크의 길이는 A1, A2, ..., AN이다. 재현이는 길이가 10인 롤케이크만 먹는다. 따라서, 롤케이크를 잘라서
www.acmicpc.net
단순 그리디라고 생각해서 작은 것부터 자를 수 있는 만큼 잘라나가는 식으로 했지만 실패했다.
왜 틀렸을까 생각해 보니
1. 길이가 20인 롤케이크는 한 번 잘라서 길이 10인 롤케이크를 2개 만들 수 있다는 점
2. 길이가 10의 배수인 롤케이크를 길이가 10으로 나누어 떨어지지 않는 롤케이크 보다 먼저 자르는 게 이득일 것이라는 점
이 같은 점들을 고려해서
1. 10으로 나누어 떨어지는 것들을 오름차순으로 앞에 오도록,
2. 10으로 나누어 떨어지지 않는 것들은 뒤 쪽에 오름차순으로
정렬했다.
std::sort(cake, cake + N, [&](int a, int b) {
if ((a % 10 == 0) && (b % 10 == 0)) {
return a < b;
} else if ((a % 10 == 0) && (b % 10 != 0)) {
return true;
} else if ((a % 10 != 0) && (b % 10 == 0)) {
return false;
} else {
return a < b;
}
});
이렇게 정렬하게 되면
5 8
34 45 20 10 30
이런 입력이 들어왔을 때
10 20 30 34 45
이렇게 정렬되게 된다.
이후 순차적으로 롤케이크의 길이를 검사한다.
1. 애초에 길이가 10이라면 정답만 1 증가하고 다음으로 넘어간다.
2. 아직 자를 수 있는 횟수가 남아있다면 10씩 자른다.
3. 자른 후에 남은 길이가 10이라면 정답을 1 증가시킨다.
코드
#include <iostream>
#include <algorithm>
int N, M;
int cake[1001];
int main() {
std::cin >> N >> M;
for (int i = 0; i < N; i++) {
std::cin >> cake[i];
}
std::sort(cake, cake + N, [&](int a, int b) {
if ((a % 10 == 0) && (b % 10 == 0)) {
return a < b;
} else if ((a % 10 == 0) && (b % 10 != 0)) {
return true;
} else if ((a % 10 != 0) && (b % 10 == 0)) {
return false;
} else {
return a < b;
}
});
int cnt = 0, cakes = 0;
bool end = false;
for (int i = 0; i < N; i++) {
int length = cake[i];
if (length == 10) {
cakes++;
continue;
}
if (end) {
continue;
}
while (length > 10) {
length -= 10;
cakes++;
cnt++;
if (cnt == M) {
end = true;
break;
}
}
if (length == 10) {
cakes++;
}
}
std::cout << cakes << "\n";
return 0;
}
'PS > BOJ' 카테고리의 다른 글
BOJ 11375 : 열혈강호 [C++] (0) | 2024.02.04 |
---|---|
BOJ 16202 : MST 게임 [C++] (0) | 2024.01.31 |
BOJ 1106 : 호텔 [C++] (0) | 2023.01.16 |
BOJ 17144 : 미세먼지 안녕! [C++] (0) | 2023.01.12 |
BOJ 17070 : 파이프 옮기기 1 [C++] (0) | 2023.01.11 |