Kattis - pizzahawaii 【状态标记】
Kattis - pizzahawaii 【状态标记】
Description
You are travelling in a foreign country. Although you are also open to eat some regional food, you just cannot resist after you have found an Italian restaurant which offers pizza. Unfortunately the menu is written in the foreign language, so the list of ingredients of the pizzas are incomprehensible to you. What will you do?
One thing that you notice is that each pizza has an Italian name, which sounds quite familiar to you. You even remember for each named pizza what the ingredients of this pizza usually are. You want to use that information to figure out what the possible meaning of each word on the list of ingredients is.
Input
The first line of the input gives the number of test cases t
(0< t≤20). The first line of each input gives the number n of pizzas on the menu (1≤n≤60). The following 3⋅n lines describe the pizzas on the menu. Each pizza description starts with one line containing the name of the pizza. The name of the pizza consists of between 3 and 20 uppercase and lowercase letters. The next line starts with an integer mi, giving the number of ingredients of the pizza on the menu (1≤mi≤20). The rest of the line contains the mi ingredients separated by spaces. Each ingredient is a word consisting of between 2 and 20
lowercase letters. The third line of each pizza description gives the ingredients in your native language in the same format. Note that the number of ingredients may differ, because each restaurant may use slightly different ingredients for pizzas with the same name, so the ingredients you remember for a pizza with that name may not match the actual ingredients.
Output
For each test case print all pairs of words (w1,w2
) where w1 is an ingredient in the foreign language that could be the same ingredient as w2 because w1 and w2 appear on the same set of pizzas. Sort the pairs in increasing lexicographical order by w1, and in case of a tie in increasing lexicographical order by w2
. Print a blank line between different test cases.
Sample Input 1
2
3
Hawaii
4 tomaten schinken ananas kaese
4 pineapple tomatoes ham cheese
QuattroStagioni
6 tomaten kaese salami thunfisch spinat champignons
6 mushrooms tomatoes cheese peppers ham salami
Capricciosa
6 champignons kaese tomaten artischocken oliven schinken
5 cheese tomatoes mushrooms ham artichoke
1
Funghi
3 tomaten kaese champignons
3 cheese tomatoes mushrooms
Sample Output 1
(ananas, pineapple)
(artischocken, artichoke)
(champignons, mushrooms)
(kaese, cheese)
(kaese, ham)
(kaese, tomatoes)
(oliven, artichoke)
(salami, peppers)
(salami, salami)
(spinat, peppers)
(spinat, salami)
(thunfisch, peppers)
(thunfisch, salami)
(tomaten, cheese)
(tomaten, ham)
(tomaten, tomatoes)
(champignons, cheese)
(champignons, mushrooms)
(champignons, tomatoes)
(kaese, cheese)
(kaese, mushrooms)
(kaese, tomatoes)
(tomaten, cheese)
(tomaten, mushrooms)
(tomaten, tomatoes)
题意
有一个人去旅行,然后发现那里的餐馆 有两份菜单。有一份是意大利语,还有一份是用英语写的。这个人就想通过几家餐馆不同的基本菜单,找出一部分意大利语与英语的对应关系。
思路
刚开始以为,一个一个对应就好了。 但是因为语法的不同,所以单词的位置可能不是一一对应的,而且可能存在一词多意。 所以不是这么简单一一对应。
但是有一个突破点就是,如果有一个单词在意大利语菜单当中出现了,那么在英语菜单当中的所有单词都可能与这个单词有对应关系。但是如果 英语菜单当中的单词 在另一本菜单中出现,而这个意大利单词没有在另一本菜单的对应菜单出现,那么说明,这两个词是一定没有关系的。
比如
A B C
D E F
G C D
D G H
我们通过第一组菜单 可以得出 A 与 D E F 都可能有对应关系。
但是 通过第二组菜单 发现 D 出现了 而 A 没有出现 所以 A 和 D 之间肯定是没有关系的。
可以通过这样的方法 来确定 但是比较繁琐
此时 我们可以引入状态标记
就是 在意大利语所有菜单中 一个单词出现的状态 如果和 英语所有菜单当中 一个单词出现的状态 一致的话 那么这两个单词是有对应关系的。
我们可以用二进制的 1 和 0 来表示状态
比如说
A B C
D E F
A G H
D F L
那么 A 的状态标记就是 1 1
D 和 F的状态标记也是 1 1 所以 A 和这两个单词是有对应关系的。
B C 的状态标记是 1 0
G H的状态标记是 0 1
等等
AC代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
const int MAX = 0x3f3f3f3f;
const int MIN = 0xc0c0c0c0;
const int maxn = 1e2 + 5;
string s[2][maxn][maxn];
int tot[2][maxn];
int main()
{
int t;
cin >> t;
map <string, string> m[2];
while (t--)
{
m[0].clear();
m[1].clear();
int n;
cin >> n;
string temp;
int i, j, k;
for (i = 0; i < n; i++)
{
cin >> temp;
for (j = 0; j < 2; j++)
{
scanf("%d", &tot[j][i]);
for (k = 0; k < tot[j][i]; k++)
{
cin >> s[j][i][k];
m[j][s[j][i][k]] = "#";
}
}
}
for (i = 0; i < 2; i++)
{
for (j = 0; j < n; j++)
{
for(k = 0; k < tot[i][j]; k++)
{
m[i][s[i][j][k]] += "1";
}
map <string, string>::iterator it;
for (it = m[i].begin(); it != m[i].end(); it++)
{
if (it -> second.size() != j + 2)
it -> second += "0";
}
}
}
map <string, string>::iterator it[2];
for (it[0] = m[0].begin(); it[0] != m[0].end(); it[0]++)
{
for (it[1] = m[1].begin(); it[1] != m[1].end(); it[1]++)
if (it[0]->second == it[1]->second)
cout << "(" << it[0]->first << ", " << it[1]->first << ")\n";
}
cout << endl;
}
}