[agc016b]colorful hats
题意:
有n个戴着帽子的人,每个人会告诉你他看到了多少种颜色的帽子,问你能不能成立,即是不是所有人都说了真话。
$n<=10^5$
题解:
其实是一道结论题但我想了很久。。。
容易发现所有人看到的颜色种类数最大值和最小值差不会超过1,否则无解;原因是两个人看到的所有帽子的差别只有各自戴着的两个。
分两种情况考虑:最大值=最小值和最小值=最大值-1;
若最大值=最小值,说明所有人看到的颜色种类都相等,那么此时要么所有人的帽子颜色互不相同,要么每种颜色的帽子至少出现两个,否则肯定会有两个人看到不同的种类数,具体来说就是戴着有多个相同颜色的帽子的人会比戴着独一无二颜色的帽子的人看到多一种(证明可以Alt+F4百度一下),那么直接判断即可;
若最小值=最大值-1,则说明值较小的人都戴着独一无二颜色的帽子,那么统计一下较小值有多少人,记为$minn$,较大值记为$max$,又因为剩下的较大值都有最少两个相同颜色的帽子,所以$max-minn\leq \frac{n-minn}{2}$,且$max-minn$要大于0,否则无解;
hint:我按照最大值是否等于最小值分类,最大值减去最小值大于一时输出"No"然而我没return 0,结果两个subtask里都输出了"NoNo",喜提fst爆0
代码:
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<cmath>
5 using namespace std;
6 int n,a[100001],tot=0,maxn=-2147483647,minn=2147483647;
7 int main(){
8 scanf("%d",&n);
9 for(int i=1;i<=n;i++){
10 scanf("%d",&a[i]);
11 maxn=max(maxn,a[i]);
12 minn=min(minn,a[i]);
13 }
14 for(int i=1;i<=n;i++)if(a[i]==minn)tot++;
15 if(maxn==minn){
16 if(maxn==n-1||maxn<=n/2)printf("Yes");
17 else printf("No");
18 }else{
19 if(maxn-minn>1)return printf("No"),0;
20 if(tot<maxn&&maxn-tot<=(n-tot)/2)printf("Yes");
21 else printf("No");
22 }
23 return 0;
24 }