关闭

HDOJ 1247 Hat’s Words (字典树分割单词枚举切割点)

351人阅读 评论(0) 收藏 举报
分类:

Hat’s Words

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11409    Accepted Submission(s): 4075


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 题意:给你一堆单词,让你求是否其中一个单词分割为两个单词而且这两个单词都在这几个单词中,例如:ahat分割 为a和hat 思路:把所有的单词都输入后,一个个暴力枚举切割点,然后查看两段单词是否存在,这个输入不知道怎么回事,所 以就一次又一次的试 ac代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stack>
#include<iostream>
#include<algorithm>
#define fab(a) (a)>0?(a):(-a)
#define LL long long
#define MAXN 55000
#define mem(x) memset(x,0,sizeof(x))
#define INF 0xfffffff 
using namespace std;
struct s
{
	int num;//标记单词的存在性
	s *next[26];
};
s *root;
char ss[MAXN][255];
int v[MAXN];
void create(char *str)
{
	int len=strlen(str);
	s *p=root,*q;
	for(int i=0;i<len;i++)
	{
		int id=str[i]-'a';
		if(p->next[id]==NULL)
		{
			q=(s *)malloc(sizeof(s));
			for(int j=0;j<26;j++)
			q->next[j]=NULL;
			q->num=0;
			p->next[id]=q;
			p=p->next[id];
		}
		else
		{
			p=p->next[id];
		}
	}
	p->num=1;
}
int find(char *ss)
{
	int len=strlen(ss);
	s *p=root;
	for(int i=0;i<len;i++)
	{
		int id=ss[i]-'a';
		p=p->next[id];
		if(p==NULL)
		return 0;//没找到
	}
	return p->num;//找到了
}
void begin()
{
	for(int i=0;i<26;i++)
	root->next[i]=NULL;
	root->num=0;
}
void freetree(s *t)
{
	if(t==NULL)
	return;
	for(int i=0;i<26;i++)
	{
		if(t->next[i]!=NULL)
		freetree(t->next[i]);
	}
	free(t);
	return;
}
int main()
{
	root=(s *)malloc(sizeof(s));
	begin();
	int k=0;
	char ne1[260],ne2[260];
	while(scanf("%s",ss[k])!=-1)
	{
		create(ss[k]);
		k++;
	}
	for(int i=0;i<k;i++)
	{
		int len=strlen(ss[i]);
		v[i]=0;
		if(len==1)
		continue;
		for(int j=1;j<len;j++)
		{
		    int qq=0;
			for(int q=0;q<j;q++)
			ne1[qq++]=ss[i][q];
			ne1[qq]='\0';
			qq=0;
			for(int q=j;q<len;q++)
			ne2[qq++]=ss[i][q];
			ne2[qq]='\0';
			if(find(ne1)&&find(ne2))//两个都能找到,标记
			{
				v[i]=1;
				break;
			}
		}
	}
	for(int i=0;i<k;i++)
	if(v[i])
	printf("%s\n",ss[i]);
	return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    时刻记住--never give up
    人生如棋,吾愿为卒,吾行虽慢,谁曾见吾后退半步!
    个人资料
    • 访问:184292次
    • 积分:8735
    • 等级:
    • 排名:第2489名
    • 原创:723篇
    • 转载:3篇
    • 译文:0篇
    • 评论:27条