HDU 1247-Hat’s Words(辞書ツリー)
3374 ワード
Hat’s Words
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4846 Accepted Submission(s): 1851
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
Sample Output
あなたにいくつかの単语をあげて、出力の中でこれらの単语の中でその他の2つの単语からつなぎ合わせたあれらの単语です.
最初から、辞書の木ですべての単語を保存し、各単語の末尾に単語の末尾をマークし、各単語を検索し、その単語のアルファベットを調べるたびに、そのアルファベットの末尾に単語の末尾を付けると、カウンタに1を加え、検索ポインタをrootに向け、残りの部分を検索し、検索が終わるまで、カウンタが2を返すと、その単語は要求に合致します.
どう見ても、考え方は正しいし、実現しやすいですが、よく考えてみると、一つの単語が二つの単語をつなぎ合わせた結果であり、三つ、四つの単語をつなぎ合わせた結果でもある場合、この単語は題意に合っているはずですが、さっきの方法で見つけたのは3、4です.どこから分割すれば問題に合致するか分からないからだ.次のデータを見てください.
a ha t aha hat ahat
aha hat ahat
さっきの考えではahatは出力されません.
それでは私达は暴力を采用するしかなくて、すべての単语に対して分割して超探して、少し时间を浪费しますが、しかし过ごすことができます!
コード:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4846 Accepted Submission(s): 1851
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
あなたにいくつかの単语をあげて、出力の中でこれらの単语の中でその他の2つの単语からつなぎ合わせたあれらの単语です.
最初から、辞書の木ですべての単語を保存し、各単語の末尾に単語の末尾をマークし、各単語を検索し、その単語のアルファベットを調べるたびに、そのアルファベットの末尾に単語の末尾を付けると、カウンタに1を加え、検索ポインタをrootに向け、残りの部分を検索し、検索が終わるまで、カウンタが2を返すと、その単語は要求に合致します.
どう見ても、考え方は正しいし、実現しやすいですが、よく考えてみると、一つの単語が二つの単語をつなぎ合わせた結果であり、三つ、四つの単語をつなぎ合わせた結果でもある場合、この単語は題意に合っているはずですが、さっきの方法で見つけたのは3、4です.どこから分割すれば問題に合致するか分からないからだ.次のデータを見てください.
a ha t aha hat ahat
aha hat ahat
さっきの考えではahatは出力されません.
それでは私达は暴力を采用するしかなくて、すべての単语に対して分割して超探して、少し时间を浪费しますが、しかし过ごすことができます!
コード:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 26
char s[50010][100];
struct node {
struct node *child[N];
int flag;
};
struct node *root;
void inital(struct node *p) {
int i;
for(i=0;i<N;i++) {
p->child[i]=NULL;
}
p->flag=0;
return;
}
void insert(char *str) {
int i,len,k;
struct node *newnode,*current;
len=strlen(str);
current=root;
if(len==0) return ;
for(i=0;i<len;i++) {
k=str[i]-'a';
if(current->child[k]!=NULL)
current=current->child[k];
else {
newnode=(struct node *)malloc(sizeof(struct node));
inital(newnode);
current->child[k]=newnode;
current=newnode;
}
}
current->flag=1;
}
int find(char *str) {
int len,i,k;
struct node *current;
current=root;
len=strlen(str);
for(i=0;i<len;i++) {
k=str[i]-'a';
if(current->child[k]!=NULL) {
current=current->child[k];
}
else
return 0;
}
return current->flag;
}
int main() {
int i,j,ans,n=0,len;
char s1[100],s2[100];
root=(struct node *)malloc(sizeof(struct node));
inital(root);
while(scanf("%s",s[n])!=EOF) {
//while(scanf("%s",s[n]),s[n][0]!='#') {
insert(s[n]);
n++;
}
for(i=0;i<n;i++) {
len=strlen(s[i]);
for(j=1;j<=len-1;j++) {
strncpy(s1,s[i],j);
s1[j]='\0';
strncpy(s2,s[i]+j,len-j);
s2[len-j]='\0';
ans=find(s1)+find(s2);
if(ans==2){
printf("%s
",s[i]);
break;
}
}
}
return 0;
}
/*
a
ha
t
aha
hat
ahat
aha
hat
ahat
*/