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的所有子串中,找出字典排序在前的。(暴力~)

代码:

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

//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解题报告(暴力、最大公共子串),布布扣,bubuko.com

时间: 2024-10-23 16:24:37

poj3080解题报告(暴力、最大公共子串)的相关文章

洛谷OJ P1032 字串变换 解题报告

洛谷OJ P1032 字串变换 解题报告 by MedalPluS   [题目描述] 已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ -> B2$ 规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$.A2$ 可以变换为 B2$ …. 例如:A$='abcd' B$='xyz' 变换规则为: ‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’ 则此时,A$ 可以经过一系列的变换变为 B$,其变换的过程为:

解题报告 之 POJ1226 Substrings

解题报告 之 POJ1226 Substrings Description You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings. Input The first li

USACO Section1.1 Broken Necklace 解题报告

beads解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------------------------------------------------------------------------------------------[题目] 输入文件:第一行N:第二行一个字符串A,长度为N.字符串中,仅有r.w.b三种字符,分别代表红.白.蓝. A代表一串项链,有三种颜

2016.7.12 NOIP2013提高组 day2解题报告(未完成版)

考试马不停蹄地到来,昨天的程序还没改完,今天又考了day2,虽然没有昨天那么懵逼,但还是不尽如人意,现在还没讲题,我打算先自己看一次解题报告,争取加深理解,毕竟一位前辈说过,做一套题的质量取决于题本身的质量和你思考的程度. 考试总结: 1.数据分析推测可行算法很重要,要灵活掌握常用算法的时间复杂度: 2.对拍的方式要熟练,写对拍耗费的时间过多: 3.要加强代码实现的能力,比较突出的表现就是写200-300行多函数模拟或搜索的能力: 4.不要急于写过不完的程序,要多拿一点时间来分析数据,样例不够还

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

codeforces 505A. Mr. Kitayuta&#39;s Gift 解题报告

题目链接:http://codeforces.com/problemset/problem/505/A 题目意思:给出一个长度不大于10的小写英文字符串 s,问是否能通过在字符串的某个位置插入一个字母,使得新得到的字符串成为回文串. /**************************************(又到自我反省时刻) 做的时候,通过添加一个单位使得长度增加1,找出中点,检验前一半的位置,找出对称位置替换成对应的前一半位置的字符,然后原字符串剩下的部分追加到后面,再判断回文.但是由于

hdu 4956 Poor Hanamichi 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4956(它放在题库后面的格式有一点点问题啦,所以就把它粘下来,方便读者观看) 题目意思:给出一个范围 [l, r] 你, 问是否能从中找到一个数证明 Hanamichi’s solution 的解法是错的. Hanamichi’s solution 是这样的: 对于某个数 X,从右往左数它的每一位数字(假设第一位是从0开始数).它 偶数位的数字之和 -  奇数位的数字之和  = 3  而且 这个 X