题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1247
题意
给你一系列字符串,问哪些字符串是由其他两个字符串(一个字符串*2也可以)一个作为前缀一个作为后缀组成的么。
思路
暴力枚举每一个字符串的前缀和后缀的中间位置,然后字典树匹配或者直接map也可以。(主要尝试一下动态建树)
代码
#define push_back pb
#define make_pair mk
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
#include<queue>
#include<stack>
#include<functional>
using std::pair;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const double PI=acos(-1);
const int maxn = 1e3 + 10;
const int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod =1e9+7;
const ll inf =1e18;
using namespace std;
int n;
struct Trie
{
struct node
{
bool end;
node* son[26];
}*root;
void init()
{
root=build();
}
node *build()
{
node *p=(node*)malloc(sizeof(node));
for(int i=0;i<26;i++) p->son[i]=NULL;
p->end=false;
return p;
}
void insert(char *s)
{
node *p;
p=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int t=s[i]-'a';
if(p->son[t]==NULL)
{
p->son[t]=build();
}
p=p->son[t];
}
p->end=true;
}
int query(char *s)
{
node *p=root;
int len=strlen(s);
for(int i=0;i<len;i++)
{
int t=s[i]-'a';
if(p->son[t]==NULL) return 0;
p=p->son[t];
}
if(p->end) return 1;
else return 0;
}
}trie;
char s[50050][50],res[50050][50];
int main()
{
int t=0;
n=0;
trie.init();
while(~scanf("%s",s[n]))
{
trie.insert(s[n++]);
t++;
}
int tot=0;
for(int i=0;i<n;i++)
{
int len=strlen(s[i]);
for(int j=1;j<len;j++)
{
char s1[50],s2[50];
memset(s1,'\0',sizeof(s1));
memset(s2,'\0',sizeof(s2));
strncpy(s1,s[i],j);
strncpy(s2,s[i]+j,len-j);
//cout<<s1<<" "<<s2<<endl;
if(trie.query(s1)&&trie.query(s2))
{
strcpy(res[tot++],s[i]);
break;
}
}
}
for(int i=0;i<tot;i++) printf("%s\n",res[i]);
}