Message Flood
Time Limit: 1500ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
Well, how do you feel about mobile phone? Your answer would probably be something like that "It's so convenient and benefits people a lot". However, If you ask Merlin this question on the New Year's Eve, he will definitely answer "What a trouble! I have to keep my fingers moving on the phone the whole night, because I have so many greeting message to send!" Yes, Merlin has such a long name list of his friends, and he would like to send a greeting message to each of them. What's worse, Merlin has another long name list of senders that have sent message to him, and he doesn't want to send another message to bother them Merlin is so polite that he always replies each message he receives immediately). So, before he begins to send message, he needs to figure to how many friends are left to be sent. Please write a program to help him. Here is something that you should note. First, Merlin's friend list is not ordered, and each name is alphabetic strings and case insensitive. These names are guaranteed to be not duplicated. Second, some senders may send more than one message to Merlin, therefore the sender list may be duplicated. Third, Merlin is known by so many people, that's why some message senders are even not included in his friend list.
输入
There are multiple test cases. In each case, at the first line there are two numbers n and m (1<=n,m<=20000), which is the number of friends and the number of messages he has received. And then there are n lines of alphabetic strings(the length of each will be less than 10), indicating the names of Merlin's friends, one per line. After that there are m lines of alphabetic strings, which are the names of message senders. The input is terminated by n=0.
输出
For each case, print one integer in one line which indicates the number of left friends he must send.
示例输入
5 3 Inkfish Henry Carp Max Jericho Carp Max Carp 0
示例输出
3
来源
第9届中山大学程序设计竞赛预选赛
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
using namespace std;
int n, m;
char a[20010][20], b[20];
struct node
{
int count; //标记为这个人为他朋友列表里的人
struct node * next[26]; //每一个节点对应着26个子节点,也就是26个英文字母,
//也就通过一个大的分叉树,将名字按顺序,以字符的形式存入到树中
};
struct node * creat() //给每个节点分配内存,开辟新的子节点,初始化节点
{
struct node * p;
p = (struct node *)malloc(sizeof(struct node));
for(int i = 0; i < 26; i++)
p->next[i] = NULL;
p->count = 0;
return p;
};
void insert(struct node * tree) //建立一棵字典树,这棵字典树里存储着按照字符顺序,以字符为节点存储所有的名字
{
struct node * p;
p = tree;
int k = strlen(b);
int t;
for(int i = 0; i < k; i++)
{
if(b[i] >= 'A' && b[i] <= 'Z') //将字符串中的字符转换为0~26对应着字典树中的26个子节点
t = b[i] - 'A';
else
t = b[i] - 'a';
if(p->next[t] == NULL) //当这个节点为叶子节点,也就是没有子节点,再给它开辟26个子节点
p->next[t] = creat();
p = p->next[t];
}
p->count = 1;
}
int search(struct node * tree, char a[])//用来查找字典树中每个字符,
{
struct node * p;
p = tree;
int k = strlen(a);
int t;
for(int i = 0; i < k; i++)
{
if(a[i] >= 'A' && a[i] <= 'Z') //同理转换为字典树每个节点所对应的子节点的坐标
t = a[i] - 'A';
else
t = a[i] - 'a';
if(p->next[t] == NULL) //当这个字符串没有查找完毕,但此时字符没有子节点
return 0; //也就是查找失败,没有找到对应的名字,返回
p = p->next[t];
}
if(p->count == 1)
return 1;
return 0;
}
void del(struct node * tree) //字典树使用完毕,清空也就是初始化
{
for(int i = 0; i < 26; i++)
{
if(tree->next[i] != NULL)
del(tree->next[i]);
}
free(tree);
}
int main() //字典树就是把所有名字按照字符存入到一棵大树中,共用节点,
{ //存完之后再和a[]字符串数组中的名字比较
while(cin >> n && n != 0)
{
cin >> m;
struct node * tree;
tree = creat();
for(int i = 0; i < n; i++)
cin >> a[i];
for(int i = 0; i < m; i++)
{
cin >> b;
insert(tree);
}
int cnt = 0;
for(int i = 0; i < n; i++)
{
int y = search(tree, a[i]);
if(y == 1)
cnt++;
}
cout << n - cnt << endl;
del(tree);
}
return 0;
}