题意:给你一堆单词,要你输出其中能由其它2个单词构成的单词
思路:首先想到能不能合并2个单词,然后再去找这个单词库,看能不能找到该单词,但是再仔细想,发现行不通,时间为合并单词所需时间[n*(n-1)/2-1]*查找时间!n最大为50000!
那么我们能不能拆了一个单词呢?时间为n个(len[i]-1)*查找时间的和,单词最长的是1913(不现实),排除这个最长的是45个字母,那么我们最坏也就是 50000*44*查找时间的情况,况且也不可能出现这种情况
所以我们采用拆单词的方法!然后直接套模板!当然,这题有个小坑
AC代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define maxn 50005
char s[maxn][50];
typedef struct node
{
int isstr;
int num;
struct node *next[27];
}trienode,*trie;
struct node *root;
void Insert(char *s)
{
int i,len=strlen(s);
trienode *p=root,*q;
for(i=0;i<len;i++)
{
if(p->next[s[i]-'a']==NULL)
{
q=(struct node *)malloc(sizeof(struct node));
memset(q->next,NULL,sizeof(q->next));
q->num=1;
q->isstr=0;
p->next[s[i]-'a']=q;
}
else
{
p->next[s[i]-'a']->num++;
}
p=p->next[s[i]-'a'];
}
p->isstr=1;
}
int find(char *s)
{
int i,len=strlen(s);
trienode *p=root,*q;
for(i=0;i<len;i++)
{
if(p->next[s[i]-'a']==NULL)
return 0;
p=p->next[s[i]-'a'];
}
if(p->isstr==1)
return 1;
return 0;
}
int main()
{
int tot=0; //记录有多少个单词
int i,j;
char str[50];
root=(struct node *)malloc(sizeof(struct node));
memset(root->next,NULL,sizeof(root->next));
root->isstr=0;
root->num=0;
while(scanf("%s",str)!=EOF)
{
strcpy(s[tot++],str);
Insert(str); //建树
}
for(i=0;i<tot;i++) //对总共有tot个单词进行拆的工作
{
for(j=1;j<strlen(s[i]);j++) //拆
{
char temp1[50]={'\0'};
char temp2[50]={'\0'};
strncpy(temp1,s[i],j); //拆单词的C函数
strncpy(temp2,s[i]+j,strlen(s[i])-j);
if(find(temp1)&&find(temp2))
{
printf("%s\n",s[i]);
break; //这里很重要,防止再次打印,就是这里没注意果断地错了,找错找了半天=-=!
}
}
}
return 0;
}