SP13117 PUCMM334 - White Hats

PUCMM334 - White Hats

题面

题意简述

一个房间里有\(n\)个人(\(2\leq n \leq 100\)),每个人都戴且仅戴着一顶黑色或白色的帽子,现在给你每个人看到的戴白帽子的人的数量(不含自己),求房间里共有几个人戴了白帽子。

输入格式

第一行有一个整数\(n\)
第二行有\(n\)个整数,表示第\(n\)个人看到的戴白帽的人的数量。

输出格式

一个整数,表示房间里戴白帽子的人的数量。若输入数据不合法,请输出-1。

解题思路

考虑特殊情况,即所有人都看到了相同的人数戴白帽。此时,我们可以简单的推断出该组数据最大值最小值是相等的。在下表中,我们假设此时一共\(3\)个人。

人数 状态 结果
\(0,0,0\) 没有人看到别人戴帽子 \(0\)
\(1,1,1\) 每个人都看到有一个人戴了帽子(不存在此种情况) \(-1\)
\(2,2,2\) 每个人都看到了其他人都戴帽子 \(3\)
\(3,3,3\) 及其他 每个人都看到了比总人数还要多的帽子 \(-1\)

发现了吗,此时我们可以进行特判,对于最大值最小值的情况,我们可以写出以下判断。

...
    if(maxhat == minhat){//若看到帽子的最大值与最小值相同
        if(maxhat == 0){//上表中0,0,0的情况
            hats = 0;
        }else if(maxhat == total - 1){//上表中2,2,2的情况
            hats = total;
        }else{//即上表中1,1,1及3,3,3的情况
            hats = -1;
        }
    }
...

关于人数的特判完成了,让我们回到一般情况。

我们不妨从最大值上再次入手去看。在此时,如果有\(n\)个人都看到了最大值maxhat时,存在以下一条规律。那就是当前的看到最大帽子数的人数最大帽子数的和等于总人数是该组数据合法的充分条件(必要吗?留给读者自行思考)。此时可以假设所有看到最大帽子数量的人没有帽子,那么此时就能得出拥有帽子数的人是最大帽子数个人。

例如在\(3\)个人,人数为\(2,1,1\)时。最大帽子数maxhat\(2\),共有\(1\)人看到了最大帽子数,其和为3。假设此人没有帽子,那么符合题意,答案为最大帽子数,即\(2\)

那么此部分判断即是:

...
    int n = 0;
    for(int i = 0;i < total;i++) if(hat[i] == maxhat) n++;
	if(maxhat + n == total) hats = maxhat;
		else hats = -1;
...

结合上文,加入输入输出,即为题解。

源程序

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int hat[100];
int maxhat = -1, minhat = 2147483647, total = 0, hats = 0,n = 0;
int main(){
    scanf("%d",&total);
    for(int i = 0;i < total;i++){
        scanf("%d",&hat[i]);
        maxhat = max(maxhat,hat[i]);
        minhat = min(minhat,hat[i]);
    }
    if(maxhat == minhat){
        if(maxhat == 0){
            hats = 0;
        }else if(maxhat == total - 1){
            hats = total;
        }else{
            hats = -1;
        }
    }else{
        int n = 0;
    	for(int i = 0;i < total;i++) if(hat[i] == maxhat) n++;
		if(maxhat + n == total) hats = maxhat;
			else hats = -1;
    }
    printf("%d",hats);
    return 0;
}

本代码已在SPOJ上评测通过

posted @ 2022-08-18 17:17  K2FeO4cn  阅读(29)  评论(0)    收藏  举报