Codeforces Round 858:B. Mex Master

发布时间 2023-03-22 21:08:45作者: Arno_vc

一、来源:Problem - B - Codeforces

二、题面

image-20230320175439445

三、思路

  1. 题面:n个非负正数,随机排列并由相邻两个数相加构成n-1个数并进行升序排列,求从0开始的第一个MEX(Minimum Excluded)

  2. 两种思考模型:

    首先可知0的数至少要过一半,接下来

    • 递归:考虑1是否能以相同情况考虑,失败
    • 分类讨论:有限类
  3. 考虑了大部分情况,主要说几个错误点

    • 对于0的分布
      • 初始想法是只要0能被全包裹,则MEX=0,将0 0 1考虑为了一个特例
      • 实际上,将0 0 1例扩展,只要0的个数小于等于1的个数最终结果即为0
    • 对于一边比另一边多一个:还是简化为超过一半的好
    • 基于0的个数已经超过n/2,不可能出现3的情况

四、代码

#include <bits/stdc++.h>
#define eleType int
#define INF 0x3f3f3f3f

typedef long long ll;

using namespace std;

const int N=2e5+10;
eleType arr[N];

int main(){
    int t;
    cin >> t;
    while(t--){
        // code
        int n;
        cin >> n;
        memset(arr,0,sizeof(int)*N);
        for(int i=0;i<n;i++){
            int temp;
            cin >> temp;
            arr[temp]++;
        }
        // 0 0 1模型可以延伸,0 0 1 1 0也是0,因此想要MEX=0,则的0个数<=(n+1)/2
        int ans=0,left=n-arr[0];
        if((n+1)/2<arr[0]){  //一边比另一边多一个:可以将逻辑简化为超过一半
            if(left==0){
                ans=1;
            }else if(left==arr[1]){
                // if(arr[1]==1){
                    ans=2;
                // }
                // else{
                //     ans=3;  //不可能有3,因为1一件超过一半了,所以至少能将1拆开
                // }
            }else{
                ans=1;
            }
        }else{
            ans=0;
        }
        cout << ans << endl;
    }
    return 0;
}