POJ1226 Substrings ——后缀数组 or 暴力+strstr()函数 最长公共子串
题目链接:https://vjudge.net/problem/POJ-1226
| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 15122 | Accepted: 5309 |
Description
Input
Output
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
Source
题意:
给出n个字符串,问是否存在一个公共子串存在于每个字符串或其逆串中,若存在,输出最长的长度。
题解:
1.将所有字符串已经其逆串拼接在一起,相邻两个之间用各异的分隔符隔开。
2.求出新串的后缀数组,然后二分公共子串的长度mid:mid将新串的后缀分成若干组,每一组对应着一个公共子串,并且长度>=mid。如果这组出现了所有字符串,那么说明当前mid合法,否则不合法。最终求得答案。
3.由于数据较弱,还可以直接暴力+kmp/strstr()函数。
后缀数组:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e5+; int id[MAXN];
int r[MAXN], sa[MAXN], Rank[MAXN], height[MAXN];
int t1[MAXN], t2[MAXN], c[MAXN]; bool cmp(int *r, int a, int b, int l)
{
return r[a]==r[b] && r[a+l]==r[b+l];
} void DA(int str[], int sa[], int Rank[], int height[], int n, int m)
{
n++;
int i, j, p, *x = t1, *y = t2;
for(i = ; i<m; i++) c[i] = ;
for(i = ; i<n; i++) c[x[i] = str[i]]++;
for(i = ; i<m; i++) c[i] += c[i-];
for(i = n-; i>=; i--) sa[--c[x[i]]] = i;
for(j = ; j<=n; j <<= )
{
p = ;
for(i = n-j; i<n; i++) y[p++] = i;
for(i = ; i<n; i++) if(sa[i]>=j) y[p++] = sa[i]-j; for(i = ; i<m; i++) c[i] = ;
for(i = ; i<n; i++) c[x[y[i]]]++;
for(i = ; i<m; i++) c[i] += c[i-];
for(i = n-; i>=; i--) sa[--c[x[y[i]]]] = y[i]; swap(x, y);
p = ; x[sa[]] = ;
for(i = ; i<n; i++)
x[sa[i]] = cmp(y, sa[i-], sa[i], j)?p-:p++; if(p>=n) break;
m = p;
} int k = ;
n--;
for(i = ; i<=n; i++) Rank[sa[i]] = i;
for(i = ; i<n; i++)
{
if(k) k--;
j = sa[Rank[i]-];
while(str[i+k]==str[j+k]) k++;
height[Rank[i]] = k;
}
} bool vis[];
bool test(int n, int len, int k)
{
int cnt = ;
memset(vis, false, sizeof(vis));
for(int i = ; i<=len; i++)
{
if(height[i]<k)
{
cnt = ;
memset(vis, false, sizeof(vis));
}
else
{
if(!vis[id[sa[i-]]]) vis[id[sa[i-]]] = true, cnt++;
if(!vis[id[sa[i]]]) vis[id[sa[i]]] = true, cnt++;
if(cnt==n) return true;
}
}
return false;
} char str[MAXN];
int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
int len = ;
for(int i = ; i<n; i++)
{
scanf("%s", str);
int LEN = strlen(str);
for(int j = ; j<LEN; j++)
{
r[len] = str[j];
id[len++] = i;
}
r[len] = +i; //分隔符
id[len++] = i;
}
for(int i = ; i<len; i++) //逆串
{
r[*len--i] = r[i];
if(r[*len--i]>=) r[*len--i] += ; //分隔符应各异
id[*len--i] = id[i];
}
len *= ;
r[len] = ;
DA(r,sa,Rank,height,len,); int l = , r = ;
while(l<=r)
{
int mid = (l+r)>>;
if(test(n,len,mid))
l = mid + ;
else
r = mid - ;
}
printf("%d\n", r);
}
}
暴力 + strstr()函数:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
typedef long long LL;
const double eps = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = +; char s[MAXN][MAXN], t1[MAXN], t2[MAXN]; int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = ; i<=n; i++)
scanf("%s", s[i]); int Len = strlen(s[]), ans = ;
for(int len = Len; len>=; len--)
{
for(int st = ; st<=Len-len; st++)
{
int en = st+len-, cnt = ;
for(int i = st; i<=en; i++)
{
t1[cnt] = s[][i];
t2[cnt++] = s[][i];
}
t1[cnt] = t2[cnt] = ;
reverse(t2,t2+cnt); bool flag = true;
for(int i = ; i<=n; i++)
flag = flag&&(strstr(s[i], t1) || strstr(s[i], t2) ); if(flag)
{
ans = len;
break;
}
}
if(ans==len) break;
}
printf("%d\n", ans);
}
}
POJ1226 Substrings ——后缀数组 or 暴力+strstr()函数 最长公共子串的更多相关文章
- poj 2774 后缀数组 两个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 31904 Accepted: 12 ...
- POJ - 3415 Common Substrings(后缀数组求长度不小于 k 的公共子串的个数+单调栈优化)
Description A substring of a string T is defined as: T( i, k)= TiTi+1... Ti+k-1, 1≤ i≤ i+k-1≤| T|. G ...
- poj2774 后缀数组2个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 26601 Accepted: 10 ...
- luogu 2463 [SDOI2008]Sandy的卡片 kmp || 后缀数组 n个串的最长公共子串
题目链接 Description 给出\(n\)个序列.找出这\(n\)个序列的最长相同子串. 在这里,相同定义为:两个子串长度相同且一个串的全部元素加上一个数就会变成另一个串. 思路 参考:hzwe ...
- URAL 1517 Freedom of Choice (后缀数组 输出两个串最长公共子串)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/whyorwhnt/article/details/34075603 题意:给出两个串的长度(一样长) ...
- POJ1226:Substrings(后缀数组)
Description You are given a number of case-sensitive strings of alphabetic characters, find the larg ...
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
- poj 3261 Milk Patterns(后缀数组)(k次的最长重复子串)
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7938 Accepted: 3598 Cas ...
- 后缀数组 模板题 hdu1403(最长公共(连续)子串)
好气啊,今天没有看懂后缀树和后缀自动机 只能写个后缀数组发泄一下了orz #include <cstdio> #include <cstring> *; int wa[N], ...
随机推荐
- Win7如何自定义鼠标右键菜单 添加新建WORD文档
鼠标右键添加新建WORD文档.reg Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\.doc] @="Word.Docume ...
- vue v-for与v-if组合使用
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中.当你想为仅有的_一些_项渲染节点时,这种优先级的机制会十分有用,如下: < ...
- 【Excle数据透视表】如何创建非共享缓存的数据透视表
一般情况下,利用同一个数据源创建多个数据表时,默认创建的是共享缓存的数据透视表.刷新一个数据透视表时会影响其他数据透视表的展示结果. 解决方案 创建非共享缓存的多个数据透视表 步骤一 单击工作表数据任 ...
- 《C陷阱与缺陷》学习笔记(一)
前言和导读 "得心应手的工具在初学时的困难程度往往超过那些easy上手的工具."比較认同这句话. 我至今认为自己事实上还是个刚入了门的刚開始学习的人. 第一章 "词法&q ...
- matlab2017b linux版分享
链接:https://pan.baidu.com/s/1smrTkFN 密码:cvb3 下载后请点关注并点赞,谢谢支持.
- Verilog代码规范(持续更新)
1.输入输出的定义,看起来整齐 2.always.if或其他语句后begin写在同一行,这样可以避免begin占用过多的行,代码密度更大 3.end后面要有注释,以标明是哪个关键词的结束,除了endc ...
- jquery判断复选框是否被选中
$("#isUse").click(function(){ if($(this).is(':checked')){ $(this).attr('checked','checked' ...
- 常用js特效
事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event.sr ...
- 2009-04-19 22:40 SQL SERVER游标的讲解
游标和游标的优点 在数据库中,游标是一个十分重要的概念.游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结 果集中每次提取一条记录的机制.游标总 ...
- CentOS下安装python3.x版本
现在python都到了3.x版本,但是centos中自带的python仍然是2.7版本的,所以想把python换成3.x版本的. 但是这个地方有个坑,你要是直接编译安装了python3.x之后,估计你 ...