Life Forms
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 10800   Accepted: 2967

Description

You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ears, eyebrows and the like. A few bear no human resemblance; these typically have geometric or amorphous shapes like cubes, oil slicks or clouds of dust.

The answer is given in the 146th episode of Star Trek - The Next Generation, titled The Chase. It turns out that in the vast majority of the quadrant's life forms ended up with a large fragment of common DNA.

Given the DNA sequences of several life forms represented as strings of letters, you are to find the longest substring that is shared by more than half of them.

Input

Standard input contains several test cases. Each test case begins with 1 ≤ n ≤ 100, the number of life forms. n lines follow; each contains a string of lower case letters representing the DNA sequence of a life form. Each DNA sequence contains at least one and not more than 1000 letters. A line containing 0 follows the last test case.

Output

For each test case, output the longest string or strings shared by more than half of the life forms. If there are many, output all of them in alphabetical order. If there is no solution with at least one letter, output "?". Leave an empty line between test cases.

Sample Input

3
abcdefg
bcdefgh
cdefghi
3
xxx
yyy
zzz
0

Sample Output

bcdefg
cdefgh ? 题意: n个字符串, 求大于n/2个字符串的最长子串。 如果有多个按字典序输出。 大致思路:首先把所有字符串用不相同的一个字符隔开(用同一个字符隔开wa了好久), 这里我是用数字来隔开的。
然后依次求sa,lcp。 我们可以二分答案的长度, 对于长度x,我们可以把 后缀进行分组(lcp[i] < x时 隔开), 然后对于每一组判断有多少个字符串出现,如果大于n/2说明符合。。对于字典序就不用排序了,,因为我们就是按照sa数组来遍历lcp的。。所以直接得到的答案就是字典序从小到大。
 #include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-;
const int M = 2e6+;
int s[M];
int sa[M], tmp[M], rank[M], lcp[M], k, len;
bool cmp(int i, int j)
{
if (rank[i] != rank[j])
return rank[i] < rank[j];
else
{
int x = i+k <= len ? rank[i+k] : -;
int y = j+k <= len ? rank[j+k] : -;
return x < y;
}
}
void build_sa()
{
for (int i = ; i <= len; i++)
{
sa[i] = i;
rank[i] = i < len ? s[i] : -;
}
for (k = ; k <= len; k *= )
{
sort (sa, sa+len+, cmp);
tmp[sa[]] = ;
for (int i = ; i <= len; i++)
{
tmp[sa[i]] = tmp[sa[i-]] + (cmp(sa[i-], sa[i]) ? : );
}
for (int i = ; i <= len; i++)
{
rank[i] = tmp[i];
}
}
}
void Get_Lcp()
{
for (int i = ; i < len; i++)
{
rank[sa[i]] = i;
}
int h = ;
lcp[] = ;
for (int i = ; i < len; i++)
{
int j = sa[rank[i]-];
if (h > )
h--;
for (; i+h < len && j+h < len; h++)
if (s[i+h] != s[j+h])
break;
lcp[rank[i]] = h;
}
}
int vis[], pos[M];
int ans[M], tot;
int Stack[M], top;
bool solve (int x, int n)
{
int minv = inf;
int cnt = ;
bool flag = false;
for (int i = ; i <= len+; i++)
{
if (lcp[i] < x)
{ if ( cnt+ (!vis[pos[sa[i-]]]) > n/ && (minv != inf && minv >= x))
{
if (!flag )
tot = ;
flag = true;
ans[tot++] = sa[i-];
}
minv = inf;
cnt = ;
memset(vis, , sizeof (vis));
continue;
}
if ( vis[pos[sa[i-]]]==)
{
cnt++; }
vis[pos[sa[i-]]] = ;
minv = min(minv, lcp[i]); }
return tot > && flag;
}
int string_len[], c1;
void init()
{
c1 = tot = ;
memset(vis, , sizeof (vis));
memset(string_len, , sizeof (string_len));
}
char cacaca[];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("wa.txt","w",stdout);
#endif
int n, cas = ;
while ( scanf ("%d", &n), n)
{
if (cas != )
printf("\n");
cas++;
init();
len = ;
int del = ;
for (int i = ; i < n; i++)
{
scanf ("%s", cacaca);
int sub_len = strlen(cacaca);
for (int j = ; j < sub_len; j++)
{
s[len++] = cacaca[j];
}
s[len++] = M+del;
del++;
string_len[c1] = sub_len + string_len[c1-];
if (c1)
string_len[c1]++;
c1++;
}
if (n == )
{
for (int i = ; i < len-; i++)
{
printf("%c", s[i]);
}
continue;
}
for (int i = , j = ; i < len; i++)
{
if (i >= string_len[j])
{
pos[i] = -;
j++;
continue;
}
pos[i] = j+;
}
build_sa();
Get_Lcp(); int ua = , ub = M;
while (ua + < ub)
{
int mid = (ua + ub) >> ;
if (mid&&solve(mid, n) == true)
{ ua = mid;
}
else
ub = mid;
}
if (tot == )
printf("?\n");
else
{
if (ua == )
{
printf("?\n");
continue;
}
for (int i = ; i < tot; i++)
{
for (int j = ans[i]; j < ans[i]+ua; j++)
{
printf("%c", s[j]);
}
printf("\n");
}
}
}
return ;
}
 

POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串的更多相关文章

  1. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

    Life Forms   Description You may have wondered why most extraterrestrial life forms resemble humans, ...

  2. poj 3294 Life Forms - 后缀数组 - 二分答案

    题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...

  3. 【poj3294-不小于k个字符串中最长公共子串】后缀数组

    1.注意每两个串之间的连接符要不一样. 2.分组的时候要注意最后一组啊!又漏了! 3.开数组要考虑连接符的数量.100010是不够的至少要101000. #include<cstdio> ...

  4. POJ 3080 Blue Jeans(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通 ...

  5. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  6. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  7. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  8. POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串

    题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072 ...

  9. cogs249 最长公共子串(后缀数组 二分答案

    http://cogs.pro:8080/cogs/problem/problem.php?pid=pxXNxQVqP 题意:给m个单词,让求最长公共子串的长度. 思路:先把所有单词合并成一个串(假设 ...

随机推荐

  1. Class loading in JBoss AS 7--官方文档

    Class loading in AS7 is considerably different to previous versions of JBoss AS. Class loading is ba ...

  2. Everything 使用技巧

    使用技巧 可以使用逻辑符空格(与), |(或),!(非),及通配符 * 和 ? ,符号或搜索内容之间必须加空格且空格任意使用如果经常搜索同一内容,可以使用书签功能,且可以对书签进行添加.编辑.排序.导 ...

  3. SpringMVC05使用注解的方式

    <body> <a href="add">新增</a> <a href="update">修改</a> ...

  4. HTML5和CSS3实例教程[总结一]

    关于onclick的行为与内容分离 通过链接触发弹出窗口方式 (不推荐使用此方法!!!) <a href='#' onclcik = "window.open('holiday_pay ...

  5. [JavaScript]plupload多图片上传图片

    var uploader = new plupload.Uploader({ //创建实例的构造方法     runtimes: 'html5,flash,silverlight,html4',    ...

  6. css空格和去浮动的应用

    今天做了项目用到css,请教前端解决,第一个是记得css空格之间的关系是隶属关系,但是在元素中却是并列关系,如<div class="right_side_item_moban gra ...

  7. android 检查网络是否可用,如果不可用弹出设置,让用户改变

    /** * 校验网络,如果没有网络,返回true * * @return boolean */ @Override public boolean hasInternetConnected() { Co ...

  8. 武汉科技大学ACM:1003: 华科版C语言程序设计教程(第二版)例题6.6.改编

    Problem Description 小明明最喜欢学英语了,英语课从来不翘课,但是英语却一直没学好,因为上课一直在睡觉.为什么会睡觉呢,因为他觉得英文单词太长了.现在小明明有一个很长很长很长的单词, ...

  9. 武汉科技大学ACM:1002: 华科版C语言程序设计教程(第二版)例题6.6

    Problem Description 明天就要英语考试了,小明明正在挑灯夜 战背单词.小明明发现单词很难背,背一个忘一个.经过仔细研究,小明明发现单词难背的原因是因为某个字符的出现,破坏了整个单词的 ...

  10. Struts2的创建Web项目入门

    之前学过javaEE开发,学了之后便去做前端了,再也没碰过javaEE.现在重新学习和部署,入门级,使用MyEclipse10版本. 简单说一下过程. struts步骤: 1. web project ...