HDU-1247 Hat’s Words
Time Limit : 2000/1000ms (Java/Other)
Memory Limit : 65536/32768K (Java/Other)
Problem Description
A hat’s word is a word in the dictionary that is the concatenation of exactly two other words in the dictionary.
You are to find all the hat’s words in a dictionary.
Input
Standard input consists of a number of lowercase words, one per line, in alphabetical order. There will be no more than 50,000 words. Only one case.
Output
Your output should contain all the hat’s words, one per line, in alphabetical order.
Sample Input
a
ahat
hat
hatword
hziee
word
Sample Output
ahat
hatword
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1247
分析
题意:如果一个单词可以由另外两个单词组成,那么就输出这个单词。所有的单词都是自己输入的。
思路:有两种解法,可以用map,也可以用字典树。我看了很长时间的字典树终于会用了,当然要用字典树来试一下手了,首先就是输入,输入的时候建立这棵树就行了,输入完之后一个for循环来进行搜索所有的单词,核心就是将单词进行拆分,可以用substr()这个函数来实现。拆分过后只需要在树种查找是否出现过拆分后的两个单词就可以了。
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
using namespace std;
typedef struct node
{
int pre;
node *next[26];
};
node root;
void CreateTire(string str)
{
int len=str.length();
node *p=&root;
node *q;
for (int i=0;i<len;i++)
{
int id=str[i]-'a';
if (p->next[id]==NULL)
{
q=(node*)malloc(sizeof(node));
q->pre=0;
for (int j=0;j<26;j++)
q->next[j]=NULL;
p->next[id]=q;
}
p=p->next[id];
if (i==len-1)
p->pre=1;
}
}
int FindTire(string str)
{
int len=str.length();
node *p=&root;
for (int i=0;i<len;i++)
{
int id=str[i]-'a';
if (p->next[id]==NULL)
return 0;
p=p->next[id];
}
return p->pre;
}
int main()
{
string word[50005];
int i=0;
for (int k=0;k<26;k++)
root.next[k]=NULL;
root.pre=0;
while (cin>>word[i])
{
CreateTire(word[i]);
i++;
}
string s1,s2;
for (int j=0;j<i;j++)
{
if (word[j].length()==1)
continue;
int len=word[j].length();
for (int k=0;k<len;k++)
{
s1=word[j].substr(0,k+1);
s2=word[j].substr(k+1,len);
int ans1=FindTire(s1);
int ans2=FindTire(s2);
if (ans1&&ans2)
{
cout<<word[j]<<endl;
break;
}
}
}
return 0;
}