查找戴白帽人数的程序
一个房间里有N个人,每个人都戴着一顶黑色或白色的帽子。每个人都计算其他戴白帽子的人数。给定每个人的计数,任务是找出戴白帽子的人数,或者如果给定的计数不对应于有效情况,则打印 -1。
例子:
Input : arr[] = {2, 1, 1}.
Output : 2
First person sees two white hats. Second
and third persons see one white hat. The
first person must be wearing a black hat
and other two must be wearing a white hat.
Input : arr[] = {2, 2, 2}
Output : 3
All are wearing white hats.
Input : arr[] = {10, 10}
Output : -1
There are only two persons, count can't be 10.
只有两种人。如果每个人都正确计数(有效情况),那么每个戴白帽子的人的计数值是相同的。而且,每个戴黑帽的人的计数值都是一样的。所以数组中只会有一种或两种类型的值。
设白帽子的数量为 i,0 <= i <= N-1。
现在观察每个戴白帽子的人,计数值为 i-1。所以会有 i 个人的计数为 i-1。
此外,戴黑帽子的人数将是 N - i,他们的给定计数值为 i。
一个有趣的案例是零白帽。如果所有值都是 0,那么每个人都戴着黑帽子。否则,当一个人戴着白帽子时,最多只能有一个零。如果为 1,则所有其他条目必须为 1。
解决这个问题的算法:
1. Count the frequency of each element of the array.
2. Since there are one or two types, say x and y.
a) If the number of x's equal to x + 1 and number
of y's equal to n - y. The Number of hats equal
to y or x + 1.
b) Otherwise print -1.
解释示例:
Suppose, N = 5, the number of white hats can be range
from 0 to 4.
For white hats = 1, array will be {0, 1, 1, 1, 1}.
Number of 0's = 0 + 1 = 1.
Number of 1's = 5 - 1 = 4.
For white hats = 2, array will be {1, 1, 2, 2, 2}.
Number of 1's = 1 + 1 = 2.
Number of 2's = 5 - 3 = 2.
For white hats = 3, array will be {2, 2, 2, 3, 3}.
Number of 2's = 2 + 1 = 3.
Number of 3's = 5 - 3 = 2.
For white hats = 5, array will be {4, 4, 4, 4, 4}.
Number of 4's = 4 + 1 = 5.
Number of 5's = 5 - 5 = 0.
下面是这种方法的实现:
CPP
// C++ program to count number of white hats
#include
using namespace std;
// Given counts of White hats seen by n people,
// return count of white hats.
int numOfWhiteHats(int arr[], int n)
{
// Counting frequencies of all values in given
// array
int freq[n+1];
memset(freq, 0, sizeof(freq));
for (int i=0; i= n)
return -1;
freq[arr[i]]++;
}
// Counting number of different frequencies
int diffFreq = 0;
for (int i = n-1; i >= 0; i--)
if (freq[i])
diffFreq++;
// Cases where all the persons wearing white hat.
if (diffFreq == 1 && freq[n-1] == n)
return n;
// Case where no one wearing white hat.
if (diffFreq == 1 && freq[0] == n)
return 0;
// Else : number of distinct frequency must be 2.
if (diffFreq != 2)
return -1;
// Finding the last frequency with non zero value.
// Note that we traverse from right side.
int k;
for (k = n-1; k >= 1; k--)
if (freq[k])
break;
// Checking number of k's must be n - k.
// And number of (k-1)'s must be k.
if (freq[k-1] == k && freq[k] + k == n)
return freq[k-1];
else
return -1;
}
// Driver code
int main()
{
int arr[] = {2, 2, 2, 3, 3};
int n = sizeof(arr)/sizeof(arr[0]);
cout << numOfWhiteHats(arr, n);
return 0;
}
Java
// Java program to count number of white hats
import java.util.Arrays;
class GFG {
// Given counts of White hats seen by n
// people, return count of white hats.
static int numOfWhiteHats(int arr[], int n)
{
// Counting frequencies of all values
// in given array
int freq[] = new int[n + 1];
Arrays.fill(freq, 0);
for (int i = 0; i < n; i++) {
// Count of White hats cannot be
// more than n for n persons.
if (arr[i] >= n)
return -1;
freq[arr[i]]++;
}
// Counting number of different
// frequencies
int diffFreq = 0;
for (int i = n - 1; i >= 0; i--)
if (freq[i] > 0)
diffFreq++;
// Cases where all the persons wearing
// white hat.
if (diffFreq == 1 && freq[n - 1] == n)
return n;
// Case where no one wearing white hat.
if (diffFreq == 1 && freq[0] == n)
return 0;
// Else : number of distinct frequency
// must be 2.
if (diffFreq != 2)
return -1;
// Finding the last frequency with non
// zero value.
// Note that we traverse from right side.
int k;
for (k = n - 1; k >= 1; k--)
if (freq[k] > 0)
break;
// Checking number of k's must be n - k.
// And number of (k-1)'s must be k.
if (freq[k - 1] == k && freq[k] + k == n)
return freq[k - 1];
else
return -1;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 2, 2, 2, 3, 3 };
int n = arr.length;
System.out.print(numOfWhiteHats(arr, n));
}
}
// This code is contributed by Anant Agarwal.
Python3
# python program to count
# number of white hats
def numOfWhiteHats(arr, n):
# Counting frequencies of
# all values in given
# array
freq=[0 for i in range(n + 1 + 1)]
for i in range(n):
# Count of White hats
# cannot be more than
# n for n persons.
if (arr[i] >= n):
return -1
freq[arr[i]]+=1
# Counting number of
# different frequencies
diffFreq = 0
for i in range(n-1,-1,-1):
if (freq[i]):
diffFreq+=1
# Cases where all the
# persons wearing white hat.
if (diffFreq == 1 and freq[n-1] == n):
return n
# Case where no one
# wearing white hat.
if (diffFreq == 1 and freq[0] == n):
return 0
# Else : number of distinct
# frequency must be 2.
if (diffFreq != 2):
return -1
# Finding the last frequency
# with non zero value.
# Note that we traverse
# from right side.
for k in range(n - 1, 0, -1):
if (freq[k]):
break
# Checking number of k's
# must be n - k.
# And number of (k-1)'s
# must be k.
if (freq[k-1] == k and freq[k] + k == n):
return freq[k-1]
else:
return -1
# Driver code
arr= [2, 2, 2, 3, 3]
n= len(arr)
print(numOfWhiteHats(arr, n))
# This code is contributed
# by Anant Agarwal.
C#
// C# program to count number of white hats
using System;
class GFG {
// Given counts of White hats seen by n
// people, return count of white hats.
static int numOfWhiteHats(int []arr, int n)
{
// Counting frequencies of all values
// in given array
int []freq = new int[n + 1];
//Arrays.fill(freq, 0);
for (int i = 0; i < n; i++) {
// Count of White hats cannot be
// more than n for n persons.
if (arr[i] >= n)
return -1;
freq[arr[i]]++;
}
// Counting number of different
// frequencies
int diffFreq = 0;
for (int i = n - 1; i >= 0; i--)
if (freq[i] > 0)
diffFreq++;
// Cases where all the persons wearing
// white hat.
if (diffFreq == 1 && freq[n - 1] == n)
return n;
// Case where no one wearing white hat.
if (diffFreq == 1 && freq[0] == n)
return 0;
// Else : number of distinct frequency
// must be 2.
if (diffFreq != 2)
return -1;
// Finding the last frequency with non
// zero value.
// Note that we traverse from right side.
int k;
for (k = n - 1; k >= 1; k--)
if (freq[k] > 0)
break;
// Checking number of k's must be n - k.
// And number of (k-1)'s must be k.
if (freq[k - 1] == k && freq[k] + k == n)
return freq[k - 1];
else
return -1;
}
// Driver code
public static void Main()
{
int []arr = {2, 2, 2, 3, 3};
int n = arr.Length;
Console.WriteLine(numOfWhiteHats(arr, n));
}
}
// This code is contributed by vt_m.
Javascript
输出:
3