大致题意:
给出n个长度为60的DNA基因(A腺嘌呤 G鸟嘌呤 T胸腺嘧啶 C胞嘧啶)序列,求出他们的最长公共子序列。
大致思路:
和poj3450差不多,改改就能过。链接:http://bbezxcy.iteye.com/blog/1405685
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int nMax = 200001;
int num[nMax];
int sa[nMax], rank[nMax], height[nMax];
int wa[nMax], wb[nMax], wv[nMax], wd[nMax];
int cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a+l] == r[b+l];
}
void da(int *r, int n, int m){ // 倍增算法 r为待匹配数组 n为总长度 m为字符范围
int i, j, p, *x = wa, *y = wb, *t;
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i;
for(j = 1, p = 1; p < n; j *= 2, m = p){
for(p = 0, i = n-j; i < n; i ++) y[p ++] = i;
for(i = 0; i < n; i ++) if(sa[i] >= j) y[p ++] = sa[i] - j;
for(i = 0; i < n; i ++) wv[i] = x[y[i]];
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[wv[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i];
for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){
x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++;
}
}
}
void calHeight(int *r, int n){ // 求height数组。
int i, j, k = 0;
for(i = 1; i <= n; i ++) rank[sa[i]] = i;
for(i = 0; i < n; height[rank[i ++]] = k){
for(k ? k -- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k ++);
}
}
int loc[nMax],m;
char str[nMax],res[nMax];
bool vis[1004];
bool check(int mid,int len){
int i,j,tot;
tot=0;
memset(vis,0,sizeof(vis));
for(i=2;i<=len;i++){
if(height[i]<mid){
memset(vis,0,sizeof(vis));
tot=0;
}
else{
if(!vis[loc[sa[i-1]]]){
vis[loc[sa[i-1]]]=1;
tot++;
}
if(!vis[loc[sa[i]]]){
vis[loc[sa[i]]]=1;
tot++;
}
if(tot==m){
for(j=0;j<mid;j++){
res[j]=num[sa[i]+j]+'A'-1;
}res[mid]='\0';
return 1;
}
}
}
return 0;
}
int main(){
int n,k,i,j,a,b,sp,ans,cas;
scanf("%d",&cas);
while(scanf("%d",&m)!=EOF){
sp=29; //分隔符
n=0;
ans=0;
for(i=1;i<=m;i++){
scanf("%s",str);
for(j=0;str[j];j++){
loc[n]=i;
num[n++]=str[j]-'A'+1;
}
loc[n]=sp;
num[n++]=sp++;
}
num[n]=0;
da(num, n + 1, sp);
calHeight(num,n);
int left=0,right=strlen(str),mid;//开始二分
while(right>=left){
mid=(right+left)/2;
if(check(mid,n)){ //判断长度为mid的串是否是所有字符串的公共子串
left=mid+1;
ans=mid;
}
else{
right=mid-1;
}
}
if(ans>=3){
printf("%s\n",res);
}
else{
printf("no significant commonalities\n");
}
}
return 0;
}
分享到:
相关推荐
【标题】"POJ3080-Blue Jeans" 是北京大学在线编程平台POJ(Problem Online Judge)上的一道算法竞赛题目。这道题目主要考察的是动态规划和数组处理的能力,是许多编程爱好者和竞赛选手在提升算法技能时会遇到的经典...
北大ACM-POJ3080 - Blue Jeans 原比赛题目的测试数据
- POJ 3349、POJ 3274:字符串匹配及Hash应用。 - POJ 2151、POJ 1840:利用Hash进行快速查询。 - POJ 2002、POJ 2503:Hash表在实际问题中的运用。 ### 搜索算法 #### 深度优先搜索 (DFS) - **题目示例**: -...
- **字符串算法**:包括后缀数组、AC自动机等。 - **组合优化**:涉及组合优化问题的求解方法。 - **数学建模**:学习如何将实际问题转化为数学模型进行求解。 - **数论算法**:包括质因数分解、扩展欧几里得算法等...
- (poj1961, poj2406):高效的字符串匹配算法。 ### 十、进阶状态压缩 1. **状态压缩技巧**: - 如何高效地表示和压缩状态。 2. **状态压缩优化**: - (poj3411, poj1724):进一步提高状态压缩动态规划的效率...
- **子串**(4.4 例题):字符串查找和匹配,可以采用KMP、Boyer-Moore或Rabin-Karp算法。 - **字符串判等**(4.1 练习题):学习如何比较两个字符串是否相等,理解字符串的比较操作。 4. **日期与时间**: - **...
- **定义**:字符串处理技术,包括字符串匹配算法等。 - **示例题目**: - poj1035 - poj3080 - poj1936 - **应用场景**:适用于文本处理、模式匹配等问题。 **2. 排序** - **定义**:包括快速排序、归并排序、...
后缀数组在此问题中的应用主要是通过计算字符串的最长公共前后缀来确定可能的主题,并结合转调的概念进行匹配。 【POJ 3261】则是一个关于子串重复的问题,我们需要找到能重复K次的最长不重叠子串。这里可以利用...
### ACM POJ PKU 最全题目分类解析 #### 动态规划(DP) 在计算机科学领域,动态规划(Dynamic Programming, DP)是一种重要的算法思想,主要用于解决多阶段决策过程中的优化问题。它通过将原问题分解成相互重叠的...
- 示例题目:poj1035, poj3080, poj1936 2. **树形结构** - 示例题目:poj2388, poj2299 3. **字典树(Trie)** - 字典树是一种高效的数据结构,用于存储大量字符串。 - 示例题目:poj2513 4. **哈希表** - ...
根据提供的文件信息,我们可以分析出该段代码是用于解决POJ平台上的2314题的一种解决方案,主要涉及到了变量管理、表达式处理等方面。下面将详细解释代码中的关键概念和实现逻辑。 ### 关键概念解析 #### Variable...
- **描述**:字符串处理技术包括字符串匹配、正则表达式等。 - **应用场景**:文本检索、模式匹配等。 - **相关题目**: - POJ 2388 - POJ 2299 #### 3. 哈希表 - **描述**:哈希表是一种基于数组实现的高效数据...
- 推荐题目:[poj1035](https://vjudge.net/problem/POJ-1035)、[poj3080](https://vjudge.net/problem/POJ-3080)、[poj1936](https://vjudge.net/problem/POJ-1936) - 堆结构通常用于实现优先队列等数据结构。 2...
- 字符串处理:如KMP算法和后缀数组,用于字符串搜索和模式匹配,如`poj1035, poj3080`。 - 排序算法:如快速排序和归并排序,用于对数据进行排序,如`poj2388, poj2299`。 - 并查集:用于处理集合的合并和查询...
- poj1035: 涉及字符串操作和模式匹配问题。 ##### 2. 排序 - **定义**: 包括快速排序、归并排序和堆排序等,用于将数据按照一定顺序排列。 - **应用场景**: 应用于几乎所有需要对数据进行排序的场景。 - **示例...
【标题】"树状数组练习:POJ 2481(JAVA)" 是一篇关于使用树状数组(也称为线段树)解决编程竞赛问题的文章。这篇文章可能详细讲解了如何运用这种数据结构来解决特定的问题POJ 2481。POJ(Programming Online Judge)...
综上所述,这个压缩包内的资料涵盖了字符串处理的多个方面,包括但不限于基本操作、模式匹配算法、字符串排序、编辑距离计算以及数据压缩。对于学习和提升在ACM竞赛中处理字符串问题的能力来说,这是一个宝贵的资源...
【标题】"树状数组练习:POJ 3067" 树状数组,也称为线段树(Segment Tree),是一种高效的数据结构,用于处理区间查询和修改问题。在这个问题中,我们通过分析POJ 3067的题目来探讨如何应用树状数组解决实际问题。...
在POJ 3261的解题过程中,我们可能需要用到后缀数组的特性,比如求解字符串的最长重复子串,或者查找某个子串出现的所有位置。这些问题都可以通过比较后缀数组中的相邻元素之间的关系来解决。 在给出的压缩文件`poj...
标题“滚动数组应用:POJ 1159”指的是一个关于编程竞赛问题的解决方案,该问题在POJ(Programming Online Judge)平台上被提出。滚动数组是一种优化动态规划算法的技术,通过巧妙地重用和更新已经计算过的状态,减少...