『题解』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;
}
posted @ 2022-04-10 14:17  仙山有茗  阅读(41)  评论(0)    收藏  举报