1 条题解
-
0
题目回顾
我们有一个数组 ,可以:
- 删除任意一个元素
- 将一个元素的值增加
目标:使数组元素的和能被 整除,求最少操作次数。
核心思路
设数组总和为 ,考虑 的余数。
情况 1:
此时已经满足要求,不需要任何操作。
答案 = 0
情况 2:
要让总和能被 整除,需要让 增加 (因为 ,模 余 )。
- 操作 2(增加 )恰好做一次,就可以让总和增加 。
- 也可以考虑删除一个元素,但删除会使总和减少,不一定更好。
结论:答案 = 1(因为一次增加操作即可)
情况 3:
要让总和能被 整除,需要让 增加 (因为 ),或者删除一个元素使得新总和模 余 。
子情况 3.1:存在一个元素 满足
删除这个元素后,总和减少 ,减少量模 余 。
原来总和 ,减去 后 。
一次删除操作即可。子情况 3.2:不存在
我们无法通过一次删除得到模 余 的总和(因为删除余 或 的元素都不行)。
那么只能通过增加操作:
一次增加操作让总和 ,两次增加操作让总和 。
因为需要总和 ,所以需要两次增加操作(可以加在同一元素或不同元素上)。结论:
- 若存在 ,答案 = 1
- 否则,答案 = 2
算法步骤
- 输入
- 对每个测试用例:
- 计算总和
- 同时检查是否存在元素 满足 ,记录标志
- 根据 判断:
- 若为 → 输出
- 若为 → 输出
- 若为 :
- 若 为真 → 输出
- 否则 → 输出
时间复杂度
- 每个测试用例
- 总 不超过 ,完全可行。
代码实现(已给出)
#include<bits/stdc++.h> using namespace std; int main(){ int t; cin>>t; while(t--){ int k; cin>>k; int ACC=0; bool hv=false; for(int i=0;i<k;i++){ int x; cin>>x; ACC+=x; if(x%3==1){ hv=true; } } if(ACC%3==0){ cout<<0<<endl; }else if(ACC%3==2){ cout<<1<<endl; }else{ // ACC%3 == 1 if(hv==true){ cout<<1<<endl; }else{ cout<<2<<endl; } } } }
总结
本题的关键是分类讨论总和模 的余数,并结合删除和增加两种操作的最小代价:
总和模 3 是否有余1元素 最少操作数 任意 有 无
一句话题解:
若总和能被 整除,答案为 ;
若总和模 余 ,答案为 ;
若总和模 余 ,且存在模 余 的元素,答案为 ,否则答案为 。
- 1
信息
- ID
- 6503
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 2
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者