『题解』CodeForces CF1660B Vlad and Candies
题目大意
给定糖的种类数 \(n\) 和一个长度为 \(n\) 的数列 \(a\),\(a_i\) 表示第 \(i\) 个种类的糖的个数。
现在要吃糖,每次吃糖的个数最多的那个种类里的一颗糖,要求不能连续两次吃同一种类里的糖,请问能否将糖吃光,能则输出 YES,否则输出 NO。
思路
每次吃糖的个数最多的那个种类里的一颗糖
注意这句话,要吃糖的个数最多的那个种类的糖。
举个例子吧:\(n=3,a=1,2,3\)。
- 第一次:吃第三类的糖。\(a=1,2,2\)。
- 第二次:吃第二类的糖,不能吃第三类的,因为第一次已经吃过了。\(a=1,1,2\)。
- 第三次:吃第三类的糖。\(a=1,1,1\)。
- 第四次:吃第一或第二类的糖,这里吃第一类。\(a=0,1,1\)。
- 第五次:吃第二或第三类的糖,这里吃第二类。\(a=0,0,1\)。
- 第六次:吃最后一颗糖。\(a=0,0,0\)。
可以尝试模拟其它例子,得出结论:\(a\) 中的最大值和次大值的差 \(\le 1\) 时,才可以将糖吃光。
若是最大值与次大值的差 \(> 1\),那么第一次会吃最大值。吃完之后,原来的最大值还是最大值,必须要再次吃最大值,违反了规定,所以不能将糖吃光。
还要加一个特判:只有一类糖时,多于一颗糖则不能吃完,否则可以。
代码
#include <iostream>
using namespace std;
const int N=2e5+5;
int t,n,a[N],maxn,nmaxn;
int main(){
cin >> t;
while(t--){
cin >> n;
for(int i=1; i<=n; i++){
cin >> a[i];
}
if(n==1){ // 特判:只有一个种类的糖
if(a[1]==1) puts("YES"); // 有一个,则可以做到
else puts("NO"); // 多于一个,做不到
continue;
}
maxn=nmaxn=0; // 初始化最大值与次大值,取 0 即可
for(int i=1; i<=n; i++){
if(a[i]>maxn){
nmaxn=maxn; // 次大值就是先前的最大值
maxn=a[i]; // 更新最大值
}else if(a[i]>nmaxn){ // a[i] 比次大值大却比最大值小时,更新次大值
nmaxn=a[i];
}
}
if(maxn-nmaxn<=1) puts("YES");
else puts("NO");
}
return 0;
}

浙公网安备 33010602011771号