poj--3080Blue Jeans KMP的简单应用

穷举第一个字符串的所有子串,然后再判断其是否是其它字符串的子串。

然后注意输出字典序最小的答案。

判断枚举的子串是不是其它字符串子串时可以使用KMP,其实也可以直接暴力,因为题目数据范围不大。

学到一个技巧:可以使用memset(str,’\0’,sizeof(str)将字符数组清空。

还有一点需要注意的是在自己组合的字符串后面一定要记得加上字符串结束标志’\0’。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char str1[100],str2[100];
int next[100],n;
char ch[10][100];

void GetNext()
{
    int j=0;
    int len=strlen(str2+1);
    next[1]=0;
    for(int i=2;i<=len;i++)
    {
        while(j>0&&str2[j+1]!=str2[i])
             j=next[j];
        if(str2[j+1]==i)
             j++;
        next[i]=j;
    }
}

int KMP()
{
    int j=0;
    int m=strlen(str2+1);
    int len=strlen(str1+1);
    for(int i=1;i<=len;i++)
    {
        while(j>0&&str2[j+1]!=str1[i])
            j=next[j];
        if(str2[j+1]==str1[i])
            j++;
        if(j==m)
            return 1;
    }
    return 0;
}

void solve(char *ans)
{
     for(int i=0;i<60;i++)
     {
         int cnt=1;
         while(cnt<=60)
         {
             int ii;
             for(int j=i;j<i+cnt;j++)
                str2[j-i+1]=ch[1][j];
             str2[cnt+1]=‘\0‘;///记得最后一位加上字符串结束标志
             for(ii=2;ii<=n;ii++)
             {
                 strcpy(str1+1,ch[ii]);
                 if(KMP()==0)
                    break;
             }
             if(ii>n)
             {
                 if(strlen(str2+1)>strlen(ans+1))
                    strcpy(ans+1,str2+1);
                 else if (strlen(str2+1)==strlen(ans+1))
                 {
                    if(strcmp(ans+1,str2+1)>0)
                        strcpy(ans+1,str2+1);
                 }
                 cnt++;
             }
             else
                break;
         }
     }
     if(strlen(ans+1)<3)
         printf("no significant commonalities\n");
     else
         printf("%s\n",ans+1);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        char ans[100];
        ///每次都必须要将ans数组清空,否则上次的答案会影响下次
        memset(ans,‘\0‘,sizeof(ans));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%s",ch[i]);
        solve(ans);
    }
  return 0;
}
时间: 2024-10-12 11:56:18

poj--3080Blue Jeans KMP的简单应用的相关文章

POJ 3080--Blue Jeans【KMP &amp;&amp; 暴力枚举】

Blue Jeans Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14316   Accepted: 6374 Description The Genographic Project is a research partnership between IBM and The National Geographic Society that is analyzing DNA from hundreds of thousa

poj - 3080-Blue Jeans

Blue Jeans Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17434   Accepted: 7728 Description The Genographic Project is a research partnership between IBM and The National Geographic Society that is analyzing DNA from hundreds of thousa

POJ 3080 Blue Jeans(KMP 最长公共子串)

Blue Jeans Description The Genographic Project is a research partnership between IBM and The National Geographic Society that is analyzing DNA from hundreds of thousands of contributors to map how the Earth was populated. As an IBM researcher, you ha

poj 3080 Blue Jeans (kmp暴力)

# include <stdio.h> # include <algorithm> # include <cstring> using namespace std; int next[100]; char pat[100]; char a[100][100]; int ma; int lenp; int n; void Getnext() { int i=0,j=-1; next[0]=-1; while(i<=lenp) { if(j==-1||pat[j]==

POJ 3080 Blue Jeans KMP解法

使用KMP寻找最长的前缀的方法,比一般的暴力法有快了很多. 本题一般的暴力法需要的是O(m*n*n*n),其中m是有多少字符串,而n是字符串长度,而使用KMP就可以把时间效率提高到O(m*n*n),减少了一个n,提高了一个档次啦. 速度快很多. 准确来说应该是利用KMP寻找一个字符串A,在另一个字符串B任意位置出现的A的最长的前缀字符串. 理解好KMP的next table就好办了.每次查找到相等字符的时候,保存好最长的前缀. 注意本题的条件:选取最前的字典顺序输出.老害我错的条件. #incl

POJ 2406Power Strings(KMP)

POJ 2406 其实就是一个简单的kmp应用: ans = n % (n - f[n]) == 0 ? n / (n - f[n]) : 1 其中f是失配函数 1 //#pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmat

POJ 3461 Oulipo KMP算法题解

本题就是给出很多对字符串,然后问一个字符串在另外一个字符串出现的次数. 就是所谓的Strstr函数啦. Leetcode有这道几乎一模一样的题目. 使用KMP算法加速,算法高手必会的算法了. 另外看见讨论说什么使用KMP还超时,最大可能是没有真正理解next table的含义,写了错误的代码,故此虽然自己运行结果正确,但是却没有真正发挥next table的作用,使得算法退化为暴力法了,所以运行正确,但超时. KMP参考: http://blog.csdn.net/kenden23/articl

poj 3270 Cow Sorting 置换群 简单题

假设初始状态为 a:2 3 1 5 4 6 则目标状态为 b:1 2 3 4 5 6且下标为初始状态中的3 1 2 4 5 6(a[3],a[1]...) 将置换群写成循环的形式 (2,3,1),(5,4),6就不用移动了. 移动方式2种 1:选循环内最小的数和其他len-1个数交换 2:选整个序列最小的数和循环内最小的数交换,转到1,再换回来. #include<cstdio> #include<queue> #include<algorithm> #include&

POJ 3069 Saruman&#39;s Army (简单贪心)

Saruman's Army Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5343   Accepted: 2733 Description Saruman the White must lead his army along a straight path from Isengard to Helm's Deep. To keep track of his forces, Saruman distributes se