HDU1800 Flying to the Mars【字典树】
原创
©著作权归作者所有:来自51CTO博客作者ITCharge的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1800
题目大意:
有N个士兵。用不同的整数表示不同的级别。级别高的士兵可以教级别低的士兵,他们可以共用一把
扫帚。一个士兵最多只能有一个学生或一个老师。问:最少需要几把扫帚。
思路:
对于士兵都不相同的士兵,只需要一把扫帚。那么问题转变为找出给出数理重复次数最多的个数。建
立字典树,将每个数当作字符串插入字典树中,记录每个数出现的次数,最后找出重复出现次数的最
大值即为所求。注意:04和4都表示4,插入的时候,应该清除掉前导零。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct TrieNode
{
int Count;
struct TrieNode *Next[10];
};
TrieNode *root;
int Max;
void Create()
{
root = new TrieNode;
memset(root->Next,NULL,sizeof(root->Next));
root->Count = 0;
}
void Insert(char *s)
{
TrieNode *p, *q;
p = root;
while(*s)
{
if(!p->Next[*s-'0'])
{
q = new TrieNode;
memset(q->Next,NULL,sizeof(q->Next));
q->Count = 0;
p->Next[*s-'0'] = q;
}
p = p->Next[*s-'0'];
s++;
}
p->Count++; //只记录每个数的个数,不记录前缀出现次数
if(p->Count > Max)
Max = p->Count;
}
char str[33];
int main()
{
int N;
while(~scanf("%d",&N))
{
Max = 0;
Create();
for(int i = 0; i < N; ++i)
{
scanf("%s",str);
int j = 0;
while(str[j] == '0')
j++;
Insert(str+j);
}
printf("%d\n",Max);
}
return 0;
}