575. Distribute Candies

解决一个糖果分配问题,确保兄弟姐妹各自获得相同数量的不同种类糖果。通过统计数组中不同糖果种类的数量,并将其与数组长度一半进行比较,找出妹妹可以获得的最大种类数量。

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

Example 1:

Input: candies = [1,1,2,2,3,3]
Output: 3
Explanation:
There are three different kinds of candies (1, 2 and 3), and two candies for each kind.
Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. 
The sister has three different kinds of candies. 

Example 2:

Input: candies = [1,1,2,3]
Output: 2
Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. 
The sister has two different kinds of candies, the brother has only one kind of candies. 

Note:

  1. The length of the given array is in range [2, 10,000], and will be even.
  2. The number in given array is in range [-100,000, 100,000].

思路:统计数组中,不一样数字的个数,然后和数组的长度的一半相比,返回两者较小值。

public class Solution {
    public int distributeCandies(int[] candies) {
        Set<Integer> set = new HashSet<Integer>();
        for(int i = 0; i < candies.length; i++) {
            set.add(candies[i]);
        }
        return Math.min(set.size(), candies.length / 2);
    }
}
Problem Statement You have an unlimited supply of two types of candies: small candies and large candies. The weight of a small candy is X grams, and the weight of a large candy is Y grams. Large candies are heavier than small candies (that is, X<Y). There are N children, numbered 1 to N. You have decided to distribute candies so that the following conditions are satisfied: For i=1,…,N, child i receives exactly A i ​ candies in total of the two types. The total weights of candies distributed to the N children are all equal. Determine whether there exists a distribution method that satisfies the conditions. If it exists, find the maximum possible value for the number of large candies distributed. DeepL 翻译    问题陈述 你有无限量的两种糖果:小糖果和大糖果。小糖果的重量是 X 克,大糖果的重量是 Y 克。大糖果比小糖果重(即 X<Y )。 有 N 个孩子,编号为 1 至 N 。 你决定分发糖果,以满足以下条件: 对于 i=1,…,N 来说, i 个孩子收到的两种糖果的总重量正好是 A i ​ 。 分给 N 个孩子的糖果的总重量都相等。 确定是否存在满足条件的分配方法。如果存在,求大号糖果分配数量的最大可能值。    Constraints 2≤N≤2×10 5 1≤A i ​ ≤10 9 1≤X<Y≤10 9 All input values are integers. DeepL 翻译    限制因素 2≤N≤2×10 5 1≤A i ​ ≤10 9 1≤X<Y≤10 9 所有输入值均为整数。    Input The input is given from Standard Input in the following format: N X Y A 1 ​ … A N ​ DeepL 翻译    输入 输入内容由标准输入法提供,格式如下 N X Y A 1 ​ … A N ​    Output If there is no distribution method that satisfies the conditions, output -1. If there exists a distribution method that satisfies the conditions, output the maximum possible value for the number of large candies distributed in such a distribution method. DeepL 翻译    输出 如果没有满足条件的分配方法,则输出 -1。 如果存在满足条件的分配方法,则输出这种分配方法所分配的大颗糖果数量的最大可能值。
最新发布
11-16
要满足题目条件,我们需要为每个孩子 $ i $ 分配恰好 $ A_i $ 颗糖果(小 + 大),并且所有孩子的糖果总重量相等。我们的目标是判断是否存在这样的分配方案,并在存在时最大化总共分发的**大糖果数量**。 --- ### **解题思路** 设: - 小糖果重量:$ X $ - 大糖果重量:$ Y $,且 $ X < Y $ - 每个孩子 $ i $ 得到 $ A_i $ 颗糖果(总数) - 设第 $ i $ 个孩子得到 $ l_i $ 颗大糖果,则小糖果数为 $ A_i - l_i $ - 第 $ i $ 个孩子的总重量为: $$ w_i = l_i \cdot Y + (A_i - l_i) \cdot X = A_i \cdot X + l_i \cdot (Y - X) $$ 我们要求所有 $ w_i $ 相等。即: $$ A_i \cdot X + l_i \cdot (Y - X) = W \quad \text{对所有 } i $$ 其中 $ W $ 是每个孩子应得的相同总重量。 整理上式: $$ l_i = \frac{W - A_i X}{Y - X} $$ 由于 $ l_i $ 必须是整数,且满足 $ 0 \leq l_i \leq A_i $,所以: - $ W \equiv A_i X \pmod{Y - X} $ 对所有 $ i $ - $ l_i \in [0, A_i] $ 为了使所有孩子有相同的 $ W $,我们可以从上述公式反推: 令 $ D = Y - X > 0 $,则: $$ W = A_i X + l_i D \Rightarrow W \equiv A_i X \pmod{D} $$ 因此,所有 $ A_i X \mod D $ 必须相等,否则无解。 --- ### **算法步骤** 1. 计算 $ D = Y - X $ 2. 计算基准余数 $ r = (A_1 \cdot X) \% D $ 3. 检查是否对所有 $ i $,都有 $ (A_i \cdot X) \% D == r $。如果不是,输出 `-1` 4. 如果是,则说明存在一个公共的 $ W $,形式为: $$ W = A_i X + l_i D \Rightarrow l_i = \frac{W - A_i X}{D} $$ 我们希望最大化 $ \sum l_i $,即总的 large candy 数量。 注意:$ W $ 必须足够大,使得所有 $ l_i \geq 0 $,但也受限于 $ l_i \leq A_i $ 但注意:$ W $ 是固定的!我们必须找到一个 $ W $,使得所有 $ l_i \in [0, A_i] $ 然而,由同余条件,所有可能的 $ W $ 构成一个等差数列: $$ W \equiv R \pmod{D}, \quad \text{where } R = (A_i X) \% D $$ 同时,$ W $ 至少要是: $$ W_{\min,i} = A_i X + 0 \cdot D = A_i X \\ W_{\max,i} = A_i X + A_i D = A_i Y $$ 所以合法的 $ W $ 必须满足: $$ \max_i(A_i X) \leq W \leq \min_i(A_i Y) $$ 更准确地说,为了每个孩子都能分配合法的 $ l_i $,必须有: $$ A_i X \leq W \leq A_i Y \quad \text{for all } i \Rightarrow W \in [\max_i(A_i X), \min_i(A_i Y)] $$ 但是注意:这个区间可能为空! 5. 所以最终判断: - 先检查所有 $ (A_i X) \% D $ 是否相同 → 得到 $ R $ - 计算 $ W_{\text{low}} = \max(A_i X) $ - 计算 $ W_{\text{high}} = \min(A_i Y) $ - 在区间 $[W_{\text{low}}, W_{\text{high}}]$ 中找最小的大于等于 $ W_{\text{low}} $ 且 $ \equiv R \pmod{D} $ 的值作为候选 $ W $ - 如果不存在这样的 $ W $,返回 -1 - 否则,取这个最小的合法 $ W $?不!我们要**最大化总的大糖果数量**! 注意: $$ l_i = \frac{W - A_i X}{D} \Rightarrow \sum l_i = \frac{1}{D} \left( N \cdot W - X \sum A_i \right) $$ 所以 $ \sum l_i $ 随 $ W $ 增大而增大! 因此,为了最大化 total large candies,我们要选择**最大的合法 $ W $**,即: $$ W^* = \max\{ W \in [W_{\text{low}}, W_{\text{high}}] \mid W \equiv R \pmod{D} \} $$ 6. 如何求最大满足同余的 $ W $? 已知 $ W \leq W_{\text{high}} $,且 $ W \equiv R \pmod{D} $ 最大的这样的 $ W $ 是: $$ W^* = W_{\text{high}} - ((W_{\text{high}} - R) \% D) $$ 但如果 $ W^* < W_{\text{low}} $,则无解。 --- ### **总结步骤** 1. 读入 $ N, X, Y, A[1..N] $ 2. $ D = Y - X $ 3. $ R = (A[0] * X) \% D $ 4. 检查所有 $ (A[i] * X) \% D == R $,否则输出 -1 5. $ W\_low = \max(A_i * X) $ 6. $ W\_high = \min(A_i * Y) $ 7. 若 $ W\_low > W\_high $,输出 -1 8. 找最大 $ W \leq W\_high $ 且 $ W \equiv R \pmod{D} $: $$ W^* = W_{\text{high}} - ((W_{\text{high}} - R) \% D) $$ (如果 $ W_{\text{high}} < R $,则无解,但因为 $ A_i X \geq 0 $, $ R < D $, 而 $ W_{\text{high}} \geq Y \geq D $? 不一定。需要处理) 更安全的方法: $$ W^* = R + D \times \left\lfloor \frac{W_{\text{high}} - R}{D} \right\rfloor $$ 如果 $ W^* < W_{\text{low}} $,则无解。 9. 计算每个 $ l_i = (W^* - A_i * X) / D $ 10. 总和即为答案。 --- ### C++ 实现 ```cpp #include <iostream> #include <vector> #include <algorithm> #include <climits> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; long long X, Y; cin >> N >> X >> Y; vector<long long> A(N); for (int i = 0; i < N; ++i) { cin >> A[i]; } long long D = Y - X; // Step 1: Check if all (A[i] * X) mod D are equal long long R = (A[0] * X) % D; if (R < 0) R += D; for (int i = 1; i < N; ++i) { long long r = (A[i] * X) % D; if (r < 0) r += D; if (r != R) { cout << -1 << endl; return 0; } } // Step 2: Compute W_low = max(A_i * X), W_high = min(A_i * Y) long long W_low = 0; long long W_high = LLONG_MAX; for (int i = 0; i < N; ++i) { long long wi_min = A[i] * X; long long wi_max = A[i] * Y; W_low = max(W_low, wi_min); W_high = min(W_high, wi_max); } if (W_low > W_high) { cout << -1 << endl; return 0; } // Step 3: Find largest W <= W_high such that W ≡ R (mod D) // W* = R + D * floor((W_high - R) / D) long long W_star; if (W_high < R) { cout << -1 << endl; return 0; } W_star = R + D * ((W_high - R) / D); // integer division truncates toward zero, but non-negative safe if (W_star < W_low) { cout << -1 << endl; return 0; } // Step 4: Compute total number of large candies long long total_large = 0; for (int i = 0; i < N; ++i) { long long li = (W_star - A[i] * X) / D; // Since W_star >= A[i]*X and step D, and divisible by mod, this is exact total_large += li; } cout << total_large << endl; return 0; } ``` --- ### 解释 - 我们利用数学推导将问题转化为同余约束和线性表达式。 - 关键观察是:总重量 $ W $ 必须对所有孩子一致,且 $ W \equiv A_i X \pmod{Y-X} $,这要求所有 $ A_i X \mod D $ 相同。 - 然后我们确定 $ W $ 的可行范围 $[ \max A_i X, \min A_i Y ]$,并在其中寻找满足同余的最大 $ W $,从而最大化 $ \sum l_i $。 - 时间复杂度 $ O(N) $,符合 $ N \leq 2 \times 10^5 $ 的要求。 --- ### 边界情况处理 - 负模运算:C++ 中 `%` 对负数可能返回负值,需调整到 $[0, D)$ - 大数:使用 `long long`,因为 $ A_i, X, Y $ 可达 $ 10^9 $,乘积可达 $ 10^{18} $,在 `long long` 范围内(约 $ 9 \times 10^{18} $) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值