Have you ever played Hanabi? If not, then you've got to try it out! This problem deals with a simplified version of the game.
Overall, the game has 25 types of cards (5 distinct colors and 5 distinct values). Borya is holding n cards. The game is somewhat complicated by the fact that everybody sees Borya's cards except for Borya himself. Borya knows which cards he has but he knows nothing about the order they lie in. Note that Borya can have multiple identical cards (and for each of the 25 types of cards he knows exactly how many cards of this type he has).
The aim of the other players is to achieve the state when Borya knows the color and number value of each of his cards. For that, other players can give him hints. The hints can be of two types: color hints and value hints.
A color hint goes like that: a player names some color and points at all the cards of this color.
Similarly goes the value hint. A player names some value and points at all the cards that contain the value.
Determine what minimum number of hints the other players should make for Borya to be certain about each card's color and value.
The first line contains integer n (1 ≤ n ≤ 100) — the number of Borya's cards. The next line contains the descriptions of n cards. The description of each card consists of exactly two characters. The first character shows the color (overall this position can contain five distinct letters — R, G, B, Y, W). The second character shows the card's value (a digit from 1 to 5). Borya doesn't know exact order of the cards they lie in.
Print a single integer — the minimum number of hints that the other players should make.
2 G3 G3
0
4 G4 R4 R3 B3
2
5 B1 Y1 W1 G1 R1
4
In the first sample Borya already knows for each card that it is a green three.
In the second sample we can show all fours and all red cards.
In the third sample you need to make hints about any four colors.
题目大意:
给你N张牌,我们已知其中牌面的内容,但是不知道手中的牌哪个对哪个,现在有两种提示,一种是提示所有颜色为XX的牌都是哪张,或者是提示所有数字为XX的牌都是哪张。问最少需要多少次操作就能知道所有的牌哪个对哪个。
思路:
1、观察到一共有五种颜色,有五种数字,那么其实我们最多猜10次就一定能够得到结果了。
那么考虑2^10枚举所有操作情况,那么对应暴力处理结果维护最小即可。
2、接下来考虑:
①如果有一种牌颜色也未知,数字也未知,那么这种牌最多只能存在一种,如果大于一种,是不行的。(就是说如果我其他牌都知道了哪个对哪个,那么剩余的这种即使我不知道其信息,但是根据排除法,我们就已知了。)
②对应每种颜色我们处理一下,对应这种颜色不知道其数字的牌的种类数只能为1或者是0,如果超过了也是不行的。
③那么同理,对应每种数字我们吹一下,如果对应这种数字不知道其颜色的牌的种类数也只能是1或者是0,如果超过了也是不行的。
那么我们根据对应枚举出来的操作情况,将其处理出来即可。
如果上述条件全部满足,那么维护可行解的最小值。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int map[15][15];
int judge(int bit)
{
int a[15];
memset(a,0,sizeof(a));
int cnt=0;
for(int i=0;i<5;i++)
{
for(int j=5;j<10;j++)
{
if(map[i][j]!=0)
{
if(((bit&(1<<i))!=0)&&((bit&(1<<j))==0))a[i]++;
if(((bit&(1<<i))==0)&&((bit&(1<<j))!=0))a[j]++;
if(((bit&(1<<i))==0)&&((bit&(1<<j))==0))cnt++;
}
}
}
if(cnt>1)return 0;
for(int i=0;i<10;i++)
{
if(a[i]>1)return 0;
}
return 1;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(map,0,sizeof(map));
char s[5];
for(int i=0;i<n;i++)
{
scanf("%s",s);
int u;
if(s[0]=='R')u=0;
if(s[0]=='G')u=1;
if(s[0]=='B')u=2;
if(s[0]=='Y')u=3;
if(s[0]=='W')u=4;
int v=s[1]-'0'+4;
map[u][v]++;
}
int ans=0x3f3f3f3f;
for(int i=0;i<(1<<10);i++)
{
if(judge(i)==1)
{
int cont=0;
int tmp=i;
while(tmp)
{
if((tmp&1)!=0)
cont++;
tmp/=2;
}
ans=min(ans,cont);
}
}
printf("%d\n",ans);
}
}