※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 24501번 문제인 blobsad이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/24502
24502번: blobsad
채완이와 주환이가 이 일을 마칠 수 있는 최소 시간을 초 단위로 출력한다. 만약, 마칠 수 없다면 blobsad를 출력한다.
www.acmicpc.net
만약 최종적으로 K의 배수가 되도록 모인 각 칸의 블롭들이 온 칸의 구간이 양 끝을 제외한 지점에서 겹친다면 그 겹친 부분의 블롭들의 움직임을 바꿔 더 적은 시간으로 블롭들을 움직일 수 있다는 것을 관찰할 수 있다.
따라서, 앞에서부터 K마리씩 블롭을 끊어 이들을 각각 한 칸으로 모으는 것이 최적의 방법중 하나이고, 이를 이용해 문제를 해결할 수 있다.
이들을 모아야하는 칸은 K = 2x+1이라면 x+1번째, K = 2x라면 x-1 또는 x번째 칸(또는 그 사이)이 된다. 그렇지 않은 칸에 모으려고 한다면 항상 더 많은 시간이 들게 된다는 것은 쉽게 확인할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
ll N, K; cin >> N >> K;
ll M = K / 2 + 1;
ll center = 0;
ll cnt = 0;
ll ans = 0;
for (ll i = 1; i <= N; i++) {
ll x; cin >> x;
if (cnt + x < K) {
cnt += x;
if (center == 0 && cnt >= M) center = i;
if (center) ans += (i - center) * x;
else ans += cnt;
}
else {
if (center) {
ans += (i - center) * (K - cnt);
x -= K - cnt;
cnt = 0;
center = 0;
}
else {
x -= K - cnt;
cnt = 0;
}
x %= K;
cnt = x;
if (cnt >= M) center = i;
else ans += cnt;
}
}
if (cnt) cout << "blobsad";
else cout << ans;
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 2331 // C++] 반복수열 (0) | 2022.03.11 |
---|---|
[BOJ 24503 // C++] blobfearful (0) | 2022.03.10 |
[BOJ 24501 // C++] blobaww (0) | 2022.03.08 |
[BOJ 24500 // C++] blobblush (0) | 2022.03.07 |
[BOJ 24499 // C++] blobyum (0) | 2022.03.06 |