题意: 在一个字符串集合里,是否有两个字符串可以构成一个字符串
思路:直接上trie树模板即可,话说trie还挺强大;但这题有个坑,一旦输出一个字符串,要立刻break,不然有可能输出多几次
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[50005][1005];
struct Trie
{
int ch[1000000][30];
int val[1000000];
int sz;
int id(char c)
{
return c - 'a';
}
void init()
{
sz = 1;
memset(val, 0, sizeof(val));
memset(ch[0], 0, sizeof(ch[0]));
}
void Insert(const char *s)
{
int u = 0, len = strlen(s);
for(int i=0; i<len; i++)
{
int c = id(s[i]);
if(!ch[u][c])
{
memset(ch[sz], 0, sizeof(ch[sz]));
ch[u][c]=sz++;
}
u = ch[u][c];
}
val[u] = 1;
}
bool Find(const char *s1, const char *s2)
{
int len1 = strlen(s1), u = 0;
for(int i=0; i<len1; i++)
{
int c = id(s1[i]);
if(!ch[u][c])
return false;
u = ch[u][c];
}
if(val[u] != 1) return false;
int len2 = strlen(s2);
u = 0;
for(int i=0; i<len2; i++)
{
int c = id(s2[i]);
if(!ch[u][c])
return false;
u = ch[u][c];
}
if(val[u] != 1) return false;
return true;
}
};
Trie trie;
char s1[1005], s2[1005];
int main()
{
trie.init();
int cnt = 0;
while(~scanf("%s", s[cnt]))
{
trie.Insert(s[cnt]);
cnt++;
//if(cnt == 7) break;
}
for(int i=0; i<cnt; i++)
{
int len = strlen(s[i]);
for(int j=1; j<len; j++)
{
int len1 = j;
int len2 = len - j;
strncpy(s1, s[i], len1);
s1[len1] = '\0';
strncpy(s2, s[i]+len1, len2);
s2[len2] = '\0';
if(trie.Find(s1, s2))
{
printf("%s\n", s[i]);
break; //一定要break
}
}
}
return 0;
}