Problem: https://atcoder.jp/contests/abc432/tasks/abc432_c
C - Candy Tribulation
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
atcoder.jp
문제 요약
작은 사탕과, 큰 사탕 두 종류의 사탕이 있다.
작은 사탕의 한 개 무게는 X, 큰 사탕의 한 개 무게는 Y일 때,
N명에게 동일한 무게의 사탕을 분배하려고 한다.
N명이 받은 큰 사탕은 몇 개인가?
단, 각각 받을 수 있는 최대 사탕 갯수는 모두 다르다.
예시1)
| 입력 | 설명(의미) |
| 3 6 8 | 3명, X = 6, Y = 8 |
| 11 10 13 | 각각 받을 수 있는 최대 사탕 개수 |
정답: 18
세 사람이 동일하게 받을 수 있는 최대 무게: 80
첫 번째 사람: 6 x 4 + 8 x 7 = 80
두 번째 사람: 6 x 0 + 8 x 10 = 80
세 번째 사람: 6 x 12 + 8 x 1 = 80
세 명이 받은 큰 사탕의 수: 7 + 10 + 1 = 18개
예시2)
| 입력 | 설명(의미) |
| 2 3 4 | 2명, X = 3, Y = 4 |
| 3 5 | 각각 받을 수 있는 최대 사탕 개수 |
정답: -1
동일한 무게로 분배할 방법이 없음
예시2)
| 입력 | 설명(의미) |
| 8 4 32 | 8명, X = 4, Y = 32 |
| 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 |
정답: 8000000000
정답이 32-bit integer를 초과할 수 있음
문제 풀이
수식으로 문제를 정리해보자.
--------------------------------------
L = 큰 사탕의 수
S = 작은 사탕의 수
T = 각 사람이 받을 수 있는 총 사탕의 수 \( (T = L + S) \)
X = 작은 사탕의 무게
Y = 큰 사탕의 무게
W = 각 사람이 가져가는 총 무게 (모두 동일)
--------------------------------------
① 사탕 개수 정리
\( T_{i} = L_{i} + S_{i} \)
\( \therefore S_{i} = T_{i} - L_{i} \)
② 사탕 무게 정리
\( W_{i} = (L_{i} * Y) + (S_{i} * X) \)
\( W_{i} = (L_{i} * Y) + {(T_{i} - L_{i}) * X} \)
\( W_{i} = L_{i}Y + T_{i}X - L_{i}X \)
\( W_{i} = L_{i}(Y - X) + (T_{i}X) \)
모든 사람은 동일한 무게 W를 가져야 하므로, \( W_{i} = W \)
③ 큰 사탕 개수 정리
\( W = L_{i}(Y - X) + (T_{i}X) \)
\( W - (T_{i}X) = L_{i}(Y - X) \)
\( \frac{W - T_{i}X}{(Y - X)} = L_{i} \)
\( L_{i} \)는 정수여야 하므로, \( (W - T_{i}X) \text{ mod } (Y - X) = 0 \)
\( L_{j} \)도 마찬가지다. \( (W - T_{j}X) \text{ mod } (Y - X) = 0 \)
(A) \( W - T_{i}X \equiv 0 \pmod {Y - X} \)
(B) \( W - T_{j}X \equiv 0 \pmod {Y - X} \)
두 식을 빼면, \( (W - T_{i}X) - (W - T_{j}X) = T_{j}X - T_{i}X = (T_{j} - T_{i})X \)
\( \therefore (T_{j} - T_{i})X \text{ mod } (Y - X) = 0 \) 를 만족하지 않으면, 사탕 분배는 불가능하다.
④ 각 사람이 가져가는 총 무게(W) 정리
\( \frac{W - T_{i}X}{(Y - X)} = L_{i} \) 를 보면, \( L_{i} \) 는 W에 대해 증가하는 선형함수이다.
즉, W가 증가하면 모든 \( L_{i} \)는 증가한다.
따라서 문제에서 요구하는 "큰 사탕의 총 개수를 최대화" 하려면, 가능한 W 중 가장 큰 W를 선택해야 한다.
단, 이 W가 실제로 존재하려면 모든 사람이 동일한 W를 가져갈 수 있는 범위 안에 있어야 한다.
정리
1. \( (T_{j} - T_{i})X \)가 \( (Y - X) \)의 배수라면, 사탕 분배 가능하다.
→ 따라서 모든 \( T_{j} \)가 \( (T_{j} - T_{0})X \equiv 0 \pmod{Y - X} \)를 만족하지 않으면, -1
2. 만족한다면, W가 올바른 범위에 있는지 확인해야 한다.
→ \( \text{max}(T_{i}X) <= W <= \text{min}(T_{i}Y) \)
풀이 코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
long long n, x, y;
cin >> n >> x >> y;
vector<int> total_candies(n, 0);
for (int i = 0; i < n; i++) cin >> total_candies[i];
// 사탕 분배가 가능한지 확인
// {(T[i] - T[0]) * x} 는 (y - x)의 배수이어야 한다.
sort(total_candies.begin(), total_candies.end());
for (int i = 1; i < total_candies.size(); i++)
{
long long impossible = (total_candies[i] - total_candies[0]) * x % (y - x);
if (impossible != 0)
{
cout << -1;
return 0;
}
}
// 공통 무게(W) 범위 계산
// T[i] * X <= W <= T[i] * Y
long long min_weight = 0;
long long max_weight = numeric_limits<long long>::max();
for (int i = 0; i < total_candies.size(); i++)
{
min_weight = max(min_weight, total_candies[i] * x);
max_weight = min(max_weight, total_candies[i] * y);
}
if (min_weight > max_weight)
{
cout << -1;
return 0;
}
// 최대 W 구하기
long long remainder = (max_weight - total_candies[0] * x) % (y - x);
max_weight = max_weight - remainder;
// large candy 개수 합 구하기
long long answer = 0;
for (int i = 0; i < n; i++)
{
answer += (max_weight - total_candies[i] * x) / (y - x);
}
cout << answer;
return 0;
}'Algorithm Problem > AtCoder' 카테고리의 다른 글
| Truck Driver (0) | 2025.11.15 |
|---|---|
| Security 2 (0) | 2025.05.25 |