杭电ACM——1247,Hat’s Words(Trie树)

这道题是有问题的,一个单词是可以被另外一个单词拼接两次得到的,如ab,abab,输出是abab,然而原题确指明,某个单词当且仅当是另外字典里的两个单词拼接的,才是一个hat’s word,实际上这道题出的不严谨,因为这个问题WA了十几次。

代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=2e5+5e4+5;
int Trie[maxn][26];
int num[maxn];
char s[50005][105];
int tot=1;
void insert(char *str)
{
	int len,node,i;
	len=strlen(str)-1;
	node=0;
	for(i=0;i<=len;i++)
	{
		if(Trie[node][str[i]-'a']==0)
			Trie[node][str[i]-'a']=tot++;
		node=Trie[node][str[i]-'a'];
	}
	num[node]++;
}
int inquire1(char *str)		//查看某个单词的后半部分是否有在字典树里面
{
	int len,i,node;
	node=0;
	len=strlen(str)-1;
	for(i=0;i<=len;i++)
	{
		if(Trie[node][str[i]-'a']==0)
			return 0;
		node=Trie[node][str[i]-'a'];
	}
	return num[node];
}
void inquire2(char *str)	//读取单词
{
	int len,flag,node,i,j;
	char s0[30];
	len=strlen(str)-1;
	node=flag=0;
	for(i=0;i<=len;i++)
	{
		if(flag)		//flag=1时,开始复制该单词后面的部分,然后进行查看
		{
			for(j=i;j<=len;j++)
				s0[j-i]=str[j];
			s0[j-i]='\0';
			if(inquire1(s0))		
			{
				printf("%s\n",str);
				break;		//是hat's word,输出后就可以结束了,避免反复输出同一个单词
			}
			flag=0;
		}
		node=Trie[node][str[i]-'a'];
		if(num[node]>=1&&i!=len)	//如果发现另外一个单词是该单词的子串(不包含它自己),则flag=1
			flag=1;
	}
}
int main()
{
	memset(Trie,0,sizeof(Trie));
	memset(num,0,sizeof(num));
	int i,j,k;
	i=0;
	while(~scanf("%s",s[i]))
	{
		insert(s[i++]);
	}
	j=0;
	while(j<i)
	{
		inquire2(s[j++]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/shamansi99/article/details/89889043