Sweety

Practice makes perfect

导航

zoj 3960 What Kind of Friends Are You?(map+哈希)

Posted on 2017-04-23 17:00  蓝空  阅读(126)  评论(0编辑  收藏  举报

What Kind of Friends Are You?

Time Limit: 1 Second      Memory Limit: 65536 KB

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 p1p2, ... , 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, 1si, 2, ... , simi (1 ≤ |sij| ≤ 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, 1ai, 2, ... , aiq (0 ≤ aij ≤ 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.

Output

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.

Sample Input

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

Sample 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

Hint

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.



问题描述:

给定 n 个待确定名字的 Friends 和 q 个问题。已知 c 个 Friends 的名字。

对于第 i 个问题,有 mi 个 Friends 会回答 yes ,其余 cmi 个 Friends 均回答 no 。

现在给定 n 个待确定名字的 Friends 以及他们对于 q 个问题的回答。若能够确定它的名字,给出;否则,输出 Let's Go to the library!!

思路:

对于回答yes的,在当前人结果上加1,而回答no时就把该friend里面的名字之外的名字加1,最后如果某个人的计数为friend的个数,就有可能是这个人,但是如果好几个符合条件的肯定就不能确定了!


#include <bits/stdc++.h>
using namespace std;
string name[205];
map<string,int>mmap;
map<string,int>::iterator iter;
int nameNum;
int sayNum;
int queSta[100][25];

int res[205];
bool tlb[25][205]; ///哈希表
int main ()
{
    //std::ios::sync_with_stdio(false);
    //std::cin.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        int queNum;
        memset(tlb,0,sizeof(tlb));

        cin>>queNum>>sayNum>>nameNum;
        for(int i=0; i<nameNum; i++)
        {
            cin>>name[i];
            mmap.insert(pair<string,int>(name[i],i));
        }

        string str;
        int Uper;
        for(int i=0; i<sayNum; i++)
        {
            cin>>Uper;
            for(int j=0; j<Uper; j++){
                cin>>str;
                tlb[i][ mmap[str] ] = 1;   ///哈希成为一张记录表,用于后续查找,如果用map在后面循环里查找,会超时
            }
        }
        for(int i=0; i<queNum; i++)
            for(int j=0; j<sayNum; j++)
               cin>>queSta[i][j];

        for(int i=0; i<queNum; i++)
        {
            memset(res,0,sizeof(res));

            for(int j=0;j<sayNum;j++) ///某个人说的是否正确
            {
                int tmp=(queSta[i][j]==1 ? 1 : -1);
                for(int k=0; k<nameNum; k++)
                    if(tlb[j][k])
                        res[k]+=tmp;
                if(queSta[i][j] == 0)
                    for(int k=0; k<nameNum; k++)
                        res[k]++;
            }
            int cnt=0,ans=-1;
            for(int j=0; j<nameNum;j++)
            {
                if(res[j] == sayNum)
                {
                    if(cnt!=0) { ans=-1; break;  }///退出 出现两个适合人选
                    else ans=j,cnt++;
                }
            }
            if(ans!=-1)  cout<<name[ans]<<endl;
            else  cout<<"Let's go to the library!!\n";
        }
    }
    return 0;
}



上面的方法可能会稍微难想一些,GPX这种就是当某个friend说的是正确(Yes)的话,就把该friend所说的名字之外的名字表里面的标记为flase,而这个朋友说的不正确(No)的话就把他提到的名字标记为flase,其本质意思就是求交集。

#include <bits/stdc++.h>
using namespace std;

int c;//, p;
char p[205][25];

int getIndex(char s[])
{
    int i;
    for (i = 0; i < c; ++i) {
        if (strcmp(s, p[i]) == 0) {
            return i;
        }
    }
    return -1;
}

int main()
{
    int T;
    int n, q;


    int m;//, s;
    char s[25];
    bool exist[25][205];
    int a;
    int i, j, k;
    bool isName[205];

    int sum;
    int index;

    scanf("%d", &T);

    while (T--) {
        scanf("%d%d", &n, &q);
        scanf("%d", &c);
        for (i = 0; i < c; ++i) {
            scanf("%s", p[i]);
        }

        memset(exist, false, sizeof(exist));
        for (i = 0; i < q; ++i) {
            scanf("%d", &m);
            for (j = 0; j < m; ++j){
                scanf("%s", s);
                exist[i][getIndex(s)] = true;//第i个问题的名字
            }
        }

        for (i = 0; i < n; ++i) {
            memset(isName, true, sizeof(isName));//初始化全部
            for (j = 0; j < q; ++j) {
                scanf("%d", &a);
                if (a == 1) {
                    for (k = 0; k < c; ++k) {
                        isName[k] = isName[k] && exist[j][k];
                    }
                } else {
                    for (k = 0; k < c; ++k) {
                        isName[k] = isName[k] && (!exist[j][k]);
                    }
                }
            }

            sum = 0;
            for (k = 0; k < c; ++k) {
                if (isName[k]) {
                    ++sum;
                    index = k;
                }
            }

            //cout << "sum = " << sum << endl;
            if (sum == 1) {
                printf("%s\n", p[index]);
            } else {
                printf("Let's go to the library!!\n");
            }
        }

    }

    return 0;
}

最后还有一种拆分了之后想的方式:也还算巧妙!here