poj3080解题报告(暴力、最大公共子串)

2024-01-20 18:38

本文主要是介绍poj3080解题报告(暴力、最大公共子串),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

POJ 3080,题目链接http://poj.org/problem?id=3080

题意:

就是求m个长度为60的字符串的最长连续公共子串,2<=m<=10

规定:

1、最长公共串长度小于3输出no significant commonalities

2、若出现多个等长的最长的子串,则输出字典序最小的串

思路:

1. 求公共最小连续子串,那么先把第一个串长度>=3的所有连续子串找出来,然后由短到长查看所有主串是否有该子串。

2. 如果发现一个公共子串,那么就开始找长度+1的公共子串;如果指定长度的所有子串都找不出一条是共有的,那么-1长度就是最长的公共子串。

例:长度为3的子串匹配时,当发现第一个长度为3的公共子串,则开始找长度为4的子串,如果发现第一个长度为4的子串,则开始找长度为5的子串,如果没有找到长度为5的公共子串,那么他们的最长公共子串长度就为4,此时就在长度为4的所有子串中,找出字典排序在前的。(暴力~

代码:

//680K	32MS
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
using std::string;
using std::vector;
#define DNA_Len 60
bool BMSearch(const char* s, const char* t)
{
const char *p = strstr(s, t);
if (p) return true;
else return false;
}
int main()
{
char temp[DNA_Len+1];
vector<string> subStr[DNA_Len+1]; // 3-60
int caseNum;
scanf("%d",&caseNum);
while (caseNum-- > 0)
{
int deqNum;//2 <= m <= 10
scanf("%d", &deqNum);
char **p = new char*[deqNum];
for (int i=0; i<deqNum; ++i)
{
p[i] = new char[DNA_Len+1];
memset(p[i], 0, DNA_Len+1);
scanf("%s", p[i]);
}
//1. 获取第一个串中 长度为3-60的所有子串   (小于3的输出no significant commonalities)
for (int len=3; len<=60; ++len){
subStr[len].clear();
for (int i=0; i<=60-len; ++i){
strncpy(&temp[0], p[0]+i, len);
temp[len] = 0;
subStr[len].push_back(temp);
}
}
//2. 子串由少到多 再deqNum个主串中查找, 如果都有该子串 则保存后查找下一个长度的子串,直到找不到
memset(temp, 0, DNA_Len+1);
bool hasOneNotGot; //标记 deqNum个主串中,如果有一个没有找到那么就为true
for (int subStrLen=3; subStrLen<=60; ++subStrLen){
for (int subNum=0,count=subStr[subStrLen].size(); subNum<count; ++subNum){
hasOneNotGot = false;
for (int strIdx=0 ; strIdx<deqNum; ++strIdx){
if (! BMSearch(p[strIdx], subStr[subStrLen].at(subNum).c_str())){	
hasOneNotGot = true; 
break;
}
}
if (! hasOneNotGot) { //找到了就退出,找下一个长度的串,没找到就继续
strcpy(temp, subStr[subStrLen].at(subNum).c_str());
break;
}
}
if (hasOneNotGot){ //该长度的子串没有找到 那么temp是最长的子串 或temp为空
break;
}
}
if (strlen(temp) >= 3){
//多个最长子串 按照字典排序
int len = strlen(temp);
vector<string> multiString;
bool searched;
for (int i=0,count=subStr[len].size(); i<count; ++i)
{
searched = true;
for (int strIdx=0 ; strIdx<deqNum; ++strIdx){
if (! BMSearch(p[strIdx], subStr[len].at(i).c_str())){	
searched = false;
break;
}
}
if (searched) multiString.push_back(subStr[len].at(i));
}
strcpy(temp, multiString.at(0).c_str());
for (int i=1,count=multiString.size(); i<count; ++i)
{
if (strcmp(temp, multiString.at(i).c_str()) > 0){
strcpy(temp, multiString.at(i).c_str());
}
}
printf("%s\n", temp);
}
else {
printf("no significant commonalities\n");
}
for (int i=0; i<deqNum; ++i) delete [](p[i]);
delete []p;
}
return 0;
}

 

 

 

这篇关于poj3080解题报告(暴力、最大公共子串)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626940

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

poj2406(连续重复子串)

题意:判断串s是不是str^n,求str的最大长度。 解题思路:kmp可解,后缀数组的倍增算法超时。next[i]表示在第i位匹配失败后,自动跳转到next[i],所以1到next[n]这个串 等于 n-next[n]+1到n这个串。 代码如下; #include<iostream>#include<algorithm>#include<stdio.h>#include<math.

poj3261(可重复k次的最长子串)

题意:可重复k次的最长子串 解题思路:求所有区间[x,x+k-1]中的最小值的最大值。求sa时间复杂度Nlog(N),求最值时间复杂度N*N,但实际复杂度很低。题目数据也比较水,不然估计过不了。 代码入下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring

spoj705( 求不相同的子串个数)

题意:求串s的不同子串的个数 解题思路:任何子串都是某个后缀的前缀,对n个后缀排序,求某个后缀的前缀的个数,减去height[i](第i个后缀与第i-1 个后缀有相同的height[i]个前缀)。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstrin

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

poj 3723 kruscal,反边取最大生成树。

题意: 需要征募女兵N人,男兵M人。 每征募一个人需要花费10000美元,但是如果已经招募的人中有一些关系亲密的人,那么可以少花一些钱。 给出若干的男女之间的1~9999之间的亲密关系度,征募某个人的费用是10000 - (已经征募的人中和自己的亲密度的最大值)。 要求通过适当的招募顺序使得征募所有人的费用最小。 解析: 先设想无向图,在征募某个人a时,如果使用了a和b之间的关系

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若

poj 2135 有流量限制的最小费用最大流

题意: 农场里有n块地,其中约翰的家在1号地,二n号地有个很大的仓库。 农场有M条道路(双向),道路i连接着ai号地和bi号地,长度为ci。 约翰希望按照从家里出发,经过若干块地后到达仓库,然后再返回家中的顺序带朋友参观。 如果要求往返不能经过同一条路两次,求参观路线总长度的最小值。 解析: 如果只考虑去或者回的情况,问题只不过是无向图中两点之间的最短路问题。 但是现在要去要回

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta