HDU 1247 Hat’s Words(字典树)题解

题意:给一个字符串集,要你给出n个字符串s,使s能被所给字符串集中的两个相加所得(ahat=a+hat)

思路:简单字典树题,注意查询的时候要判断所指next是否为NULL,否则会RE非法访问。

代价:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<string>
#include<stack> 
#include<set>
#include<map>
#include<vector>
#include<iostream>
#include<algorithm>
#include<sstream>
#define ll long long
const int N=50005;
const int INF=1e9;
using namespace std;
char s[N][55];
struct Trie{
	int num;
	Trie *next[26];
	Trie(){
		num=0;
		for(int i=0;i<26;i++){
			next[i]=NULL;
		}
	}
};
Trie *root;

void insert(char s[]){
	int len=strlen(s);
	Trie *p=root;
	for(int i=0;i<len;i++){
		int v=s[i]-'a';
		if(p->next[v]==NULL){
			p->next[v]=new Trie();	
		}
		p=p->next[v];
	}
	if(!p->num){
		p->num=1;
	}
}
int query(char s[],int rt){	//rt代表这是前半个单词还是后半个 
	int len=strlen(s),v;
	Trie *p=root;
	for(int i=0;i<len;i++){
		v=s[i]-'a';
		if(p->next[v]!=NULL){	//注意加这一步,防止RE 
			p=p->next[v];
		}
		else return 0;
		if(rt==1 && p->num && i!=len-1){	//rt==1才能查看是否能由两个单词拼接 
			if(query(s+i+1,2)){
				return -1;
			}
		} 
	}
	return p->num;
}
/*void del(Trie *p){
	if(p==NULL) return;
	for(int i=0;i<26;i++){
		if(p->next[i]!=NULL) del(p->next[i]);
	}
	delete p;
}*/
int main(){
	int cnt=0;
	int flag;
	root=new Trie();
	while(scanf("%s",s[cnt])!=EOF){
		insert(s[cnt++]);
	}
	for(int i=0;i<cnt;i++){
		flag=0;
		flag=query(s[i],1);
		if(flag==-1){
			printf("%s\n",s[i]);
		}
	}
    return 0;  
}  

猜你喜欢

转载自blog.csdn.net/qq_14938523/article/details/80274423