「The 14th Zhejiang Provincial」 C.What Kind of Friends Are You?

描述

传送门:我是传送门

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?

输入

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.

输出

For 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.

样例

输入

2
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 1

输出

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

Note

The explanation for the first sample test case is given as follows:

As Serval is the only known animal who gives a “yes” answer to the 1st, 2nd and 4th question, and gives a “no” answer to the 3rd question, we output “Serval” (without quotes) on the first line.

As no animal is known to give a “no” answer to all the questions, we output “Let’s go to the library!!” (without quotes) on the second line.

Both Alpaca and Moose give a “yes” answer to the 1st question, and a “no” answer to the 2nd, 3rd and 4th question. So we can’t determine the name of the third Friends need to be identified, and output “Let’s go to the library!!” (without quotes) on the third line.

思路

题面真是又臭又长,直接读样例看明白的题意

队友一开始思路错了告诉我搞个矩阵,我又错误的理解了他的意思,想了想觉得可行,于是就调了好久的BUG以后得到了正确的答案2333333333

赛后在网络上搜了一些其他人的题解,简单打开了两个,有用二进制的,还有用哈希的,也有用状态压缩的,似乎我这种解法是独一家,23333333

提交的时候忘记删除freopen()导致得到了两发re,删除后得到了一个1000ms的AC,差点没笑死我。但是我刚才又试着提交了一下变成了350msAC了,看来zoj的评测机也有点迷。。。

1000msAC

我的解法其实不难理解,以第二个样例为例,我们首先用map来建立一个映射,map[string] = i;表示string这个单词是第i次出现的

string

然后在输入的时候进行处理,处理完以后应该是一个qxc的矩阵

1表示在这个人这里有这个string,0表示没有

矩阵

接下来我们便可以用上边这个qxc的矩阵的每一来与下图中的每一进行对比

n

如果我们可以找到唯一匹配的,比如下图中的最后一行(1,0,1,1,1)便与矩阵第k列是唯一匹配的,这时我们可以输出k,其他情况输出”Let’s go to the library!!”。

输出的时候我们可以用string[]将一开始所有string都存储起来,然后匹配的时候记录一下下标,便可以很方便的直接输出string[下标];

时间原因写的比较乱,不过大体思路是这样的,具体细节看代码吧

在删除我一开始写的乱七八糟的调试以后代码倒是并不算很长

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include<bits/stdc++.h>
#define ll long long
using namespace std;
string s,s1[310];
map<string,int> m;
int a[310][310];
int b[310][310];
int t,n,q,c,te;

// 调试时用的函数
void print()
{
printf("----------------------\n");
for(int i = 1;i <= q;i++)
{
for(int j = 1;j <= c;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("----------------------\n");
}

int main()
{

std::ios::sync_with_stdio(false);
cin >> t;
while(t--)
{
memset(a,0,sizeof a);
memset(b,0,sizeof b);
m.clear();
cin >> n >> q;
cin >> c;
for(int i = 1;i <= c;i++)
{
cin >> s1[i];
m[s1[i]] = i;
}
for(int i = 1;i <= q;i++)
{
cin >> te;
for(int j = 1;j <= te;j++)
{
cin >> s;
a[i][m[s]] = 1;
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= q;j++)
cin >> b[i][j];
}
bool flag = 0;
int p = 0,tim = 0;
for(int i = 1;i <= n;i++)
{
// tim变量用来记录匹配的次数,只有唯一匹配才是有效的
tim = 0;
for(int j = 1;j <= c;j++)
{
flag = 0;
for(int k = 1;k <= q;k++)
{
if(a[k][j] != b[i][k])
flag = 1;
}
if(flag == 0)
{
// 变量p来记录下标
p = j;
tim++;
}
}
if(p != 0 && tim == 1)
{
cout << s1[p] << endl;
}
else
{
cout << "Let's go to the library!!" << endl;
}
p = 0;
}

}
return 0;
}