Japari Park is a large zoo home to extant species, endangered species, extinct species, cryptids and some legendary creatures. Due to a mysterious substance known as Sandstar, all the animals have become anthropomorphized into girls known as Friends.
Kaban is a young girl who finds herself in Japari Park with no memory of who she was or where she came from. Shy yet resourceful, she travels through Japari Park along with Serval to find out her identity while encountering more Friends along the way, and eventually discovers that she is a human.
However, Kaban soon finds that it's also important to identify other Friends. Her friend, Serval, enlightens Kaban that she can use some questions whose expected answers are either "yes" or "no" to identitfy a kind of Friends.
To be more specific, there are n Friends need to be identified. Kaban will ask each of them q same questions and collect their answers. For each question, she also gets a full list of animals' names that will give a "yes" answer to that question (and those animals who are not in the list will give a "no" answer to that question), so it's possible to determine the name of a Friends by combining the answers and the lists together.
But the work is too heavy for Kaban. Can you help her to finish it?
Input
There are multiple test cases. The first line of the input is an integer T (1 ≤ T ≤ 100), indicating the number of test cases. Then T test cases follow.
The first line of each test case contains two integers n (1 ≤ n ≤ 100) and q (1 ≤ q ≤ 21), indicating the number of Friends need to be identified and the number of questions.
The next line contains an integer c (1 ≤ c ≤ 200) followed by c strings p1, p2, ... , pc (1 ≤ |pi| ≤ 20), indicating all known names of Friends.
For the next q lines, the i-th line contains an integer mi (0 ≤ mi ≤ c) followed by mi strings si, 1, si, 2, ... , si, mi (1 ≤ |si, j| ≤ 20), indicating the number of Friends and their names, who will give a "yes" answer to the i-th question. It's guaranteed that all the names appear in the known names of Friends.
For the following n lines, the i-th line contains q integers ai, 1, ai, 2, ... , ai, q (0 ≤ ai, j ≤ 1), indicating the answer (0 means "no", and 1 means "yes") to the j-th question given by the i-th Friends need to be identified.
It's guaranteed that all the names in the input consist of only uppercase and lowercase English letters.
OutputFor each test case output n lines. If Kaban can determine the name of the i-th Friends need to be identified, print the name on the i-th line. Otherwise, print "Let's go to the library!!" (without quotes) on the i-th line instead.
Sample Input2 3 4 5 Serval Raccoon Fennec Alpaca Moose 4 Serval Raccoon Alpaca Moose 1 Serval 1 Fennec 1 Serval 1 1 0 1 0 0 0 0 1 0 0 0 5 5 11 A B C D E F G H I J K 3 A B K 4 A B D E 5 A B K D E 10 A B K D E F G H I J 4 B D E K 0 0 1 1 1 1 0 1 0 1 1 1 1 1 1 0 0 1 0 1 1 0 1 1 1Sample Output
Serval Let's go to the library!! Let's go to the library!! Let's go to the library!! Let's go to the library!! B Let's go to the library!! K
题意:有n个Friends和q个问题,存在c个名字,每个问题后出现的名字表示这些名字的答案为yes,未出现的名字的答案为no,给定一个行数为n,列数为q的二维表,1表示第i个Friends下问题j为yes,0表示为no,对于二维表任意一行i,如果存在唯一一个名字在q个问题中答案情况对应第i行的答案情况,则输出该名字,否则输出"Let's go to the library!!"
思路1:建立每个名字回答问题答案的二进制哈希表,每读入一个Friends的回答问题分布情况时,计算出该答案分布情况的二进制数值,查找哈希表中是否有唯一与之对应的值。
思路2,:类似于哈希思想,不过不是用二进制存值,而是直接存每个名字在每个问题下的分布情况,再分别和二维表的每行的每一列进行比较。
总结:初始化真的很重要,这次又是因为没有初始化导致一直错误
建哈希表的方法
#include<stdio.h>
#include<cstdio>
#include<algorithm>
#include<map>
#include<iostream>
#include<string.h>
#include<string>
#include<vector>
using namespace std;
const int maxn = 210;
map<string,int>id;
vector<string>num[maxn];
int main()
{
int t,n,m,q;
int c,i,j,k;
int number,cnt,flag;
string name;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
scanf("%d",&c);
for(i = 1; i <= c; i ++)
{
num[i].clear();
id.clear();
}
for(i = 1; i <= c; i ++)
{
cin>>name;
num[i].push_back(name);//记录编号为i时的名字
}
for(i = 1; i <= q; i ++)
{
scanf("%d",&number);
for(j = 1; j <= number; j ++)
{
cin>>name;//读入名字
id[name] += (1<<i);//建立名字哈希表
}
}
for(i = 1; i <= n; i ++)
{
cnt = 0;
for(j = 1; j <= q; j ++)
{
scanf("%d",&number);
if(number == 1)
cnt += (1<<j);//计算第i种物种的哈希值
}
flag = 0;
for(j = 1; j <= c; j ++)
{
if(id[num[j][0]] == cnt)//哈希值相等时
{
flag ++;//记录等值数量
k = j;
}
}
if(flag == 1)//如果有唯一一个与之对应
{
name = num[k][0];//输出名字
cout<<name<<endl;
}
else
printf("Let's go to the library!!\n");
}
}
利用c++映射容器找一一对应关系(其实还是用到了哈希思想)
#include<stdio.h>
#include<cstdio>
#include<algorithm>
#include<map>
#include<iostream>
#include<string.h>
#include<string>
#include<vector>
using namespace std;
const int maxn = 210;
int vis[maxn][maxn],book[maxn][maxn];
map<string,int>id;
vector<string>num[maxn];
struct node{
int number;
string name;
};
int main()
{
int t,n,m,q,c,i,j,number,cnt,k;
string name,name2;
struct node vis2[maxn];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
scanf("%d",&c);
memset(vis,0,sizeof(vis));
for(i = 1; i <= c; i ++)
{
vis2[i].number = 0;
num[i].clear();
id.clear();
}
for(i = 1; i <= c; i ++)
{
cin>>name;//读入名字
num[i].push_back(name);//记录编号为i时的名字
id[name] = i;//给每个名字编号为i
}
for(i = 1; i <= q; i ++)
{
scanf("%d",&number);
getchar();
for(j = 1; j <= number; j ++)
{
cin>>name2;//读入名字
vis[id[name2]][i] = 1;//对应名字的问题为yes
}
}
for(i = 1; i <= n; i ++)
for(j = 1; j <= q; j ++)
scanf("%d",&book[i][j]);
for(i = 1; i <= n; i ++)
{
for(k = 1; k <= c; k ++)
{
cnt = 0;
for(j = 1; j <= q; j ++)
{
if(vis[k][j] != book[i][j])
cnt ++;
}
if(!cnt)//第k个名字回答问题的分布情况与二维数组对应
{
vis2[i].name = num[k][0];
vis2[i].number++;//记录下相同情况的名字个数
}
}
}
for(i = 1; i <= n; i ++)
{
if(vis2[i].number == 1)//如果第n个物种有唯一的名字与之对应,输出名字
{
cout<<vis2[i].name<<endl;
}
else
printf("Let's go to the library!!\n");
}
}
return 0;
}