※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 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

+ Recent posts