题目是牛仔裤的意思,不过看不出题意和Blue Jeans有什么关系。
本题的数据是很水的,数据量小,故此可以使用非常暴力的方法过,也可以使用不那么暴力的KMP过。
这里使用更加不暴力的Trie后缀树过,这种解法就一点都不水了,呵呵。
思路:
1 建立所有字符串的后缀Trie树
2 增加额外信息,看每过路径是否是所有的字符串都经过了,如果是,那么就是合法的字符串了,查找最长的这样的字符串
3 优化一下:如果不是所有字符串的经过的路径,那么就可以直接返回,不往下搜索了
最后,我发现删除Trie都是很耗时的,不释放Trie那么速度是快很多的,需要内存自然高很多。
#include <stdio.h>
#include <string.h>
const int MAX_N = 61;
const int ALP_LEN = 4;
const int SIGNIFICANT = 3;
char DNAStr[MAX_N];
inline int charToint(char a)
{
switch (a)
{
case 'A':
return 0;
case 'T':
return 1;
case 'G':
return 2;
case 'C':
return 3;
}
return -1;//unexpected input
}
inline char intTochar(int i)
{
switch (i)
{
case 0:
return 'A';
case 1:
return 'T';
case 2:
return 'G';
case 3:
return 'C';
}
return '?';//unexpected input
}
struct Node
{
int n, tab;
Node *alpha[ALP_LEN];
Node():n(0), tab(-1)
{
for (int i = 0; i < ALP_LEN; i++)
{
alpha[i] = NULL;
}
}
};
void delTrie(Node *rt)
{
if (rt)
{
for (int i = 0; i < ALP_LEN; i++)
{
if (rt->alpha[i]) delTrie(rt->alpha[i]);
rt->alpha[i] = NULL;
}
delete rt;
}
}
Node *Trie;
int tab;
void insert(char *chs, int len)
{
Node *pCrawl = Trie;
for (int i = 0; i < len; i++)
{
int k = charToint(chs[i]);
if (!pCrawl->alpha[k]) pCrawl->alpha[k] = new Node;
pCrawl = pCrawl->alpha[k];
if (pCrawl->tab != tab)//防止重复计算
{
pCrawl->tab = tab;
pCrawl->n++;
}
}
if (pCrawl->tab != tab)
{
pCrawl->tab = tab;
pCrawl->n++;
}
}
int maxLen, pid, n;
char path[MAX_N], res[MAX_N];
void search(Node *rt)
{
for (int i = 0; i < ALP_LEN; i++)
{
if (rt->alpha[i] && rt->alpha[i]->n == n)
{
path[pid++] = intTochar(i);
if (maxLen < pid)
{
maxLen = pid;
path[pid] = '\0';
strncpy(res, path, pid+1);
}
search(rt->alpha[i]);
pid--;
}
}
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
Trie = new Node;
scanf("%d", &n);
getchar(); // get rid of '\n'
tab = 0;
for (int i = 0; i < n; i++)
{
gets(DNAStr);
int len = MAX_N-1;
tab++;
for (char *p = &DNAStr[0]; *p; p++)
{
insert(p, len);
len--;
}
}
maxLen = 0, pid = 0;
search(Trie);
if (maxLen < SIGNIFICANT)
{
puts("no significant commonalities");
}
else
{
printf("%s\n", res);
}
//delTrie(Trie);
}
return 0;
}