http://acm.hdu.edu.cn/showproblem.php?pid=1247
因为是两个词拼接,因此我们可以建两棵前缀树 遍历时分别记录true的位置看是否匹配。MLE无数发!也是醉了!
AC代码:
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxnode = 100010;
vector <string> ans;
string str[maxnode];
int cnt1,cnt2,ans1[105],ans2[105],a,b;
struct Trie{
bool flag;
int next[30];
}zt[maxnode],ft[maxnode];
void Init(){
cnt1 = cnt2 = 1;
for(int i=0; i<maxnode; i++){
memset(zt[i].next, -1, sizeof(zt[i].next));
memset(ft[i].next, -1, sizeof(ft[i].next));
zt[i].flag = false;
ft[i].flag = false;
}
}
void Insert1(string s){
int p = 0, n = s.length();
for(int i=0; i<n; i++){
if(zt[p].next[s[i]-'a'] == -1)
zt[p].next[s[i]-'a'] = cnt1++;
p = zt[p].next[s[i]-'a'];
}
zt[p].flag = true;
}
void Insert2(string s){
int p = 0, n = s.length();
for(int i=n-1; i>=0; i--){
if(ft[p].next[s[i]-'a'] == -1)
ft[p].next[s[i]-'a'] = cnt2++;
p = ft[p].next[s[i]-'a'];
}
ft[p].flag = true;
}
void Query1(string s){
a = 0;
memset(ans1, 0, sizeof(ans1));
int p = 0, n = s.length(), tmp = 0;
for(int i=0; i<n; i++){
if(zt[p].flag) if(tmp < n) ans1[a++] = tmp;
p = zt[p].next[s[i]-'a'];
tmp++;
}
}
void Query2(string s){
b = 0;
memset(ans2, 0, sizeof(ans2));
int p = 0, n = s.length(), tmp = 0;
for(int i=n-1; i>=0; i--){
if(ft[p].flag) if(tmp < n) ans2[b++] = tmp;
p = ft[p].next[s[i]-'a'];
tmp++;
}
}
int main(){
//freopen("in.txt","r", stdin);
Init();
string tmp;
int num = 0;
while(cin >> tmp){
str[num] = tmp;
num++;
}
for(int i=0; i<num; i++){
Insert1(str[i]);
Insert2(str[i]);
}
for(int i=0; i<num; i++){
Query1(str[i]);
Query2(str[i]);
bool flag = false;
for(int u=0; u<a; u++){
if(ans1[u]){
int key = str[i].length() - ans1[u];
for(int v=0; v<b; v++){
if(ans2[v] == key){
ans.push_back(str[i]);
flag = true;
break;
}
}
}
if(flag) break;
}
}
// sort(ans.begin(), ans.end());
for(vector <string>::iterator iter=ans.begin(); iter!=ans.end(); iter++)
cout << *iter << endl;
return 0;
}