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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值