HDU 1238 Substrings(KMP+暴力枚举)

来源:互联网 发布:小学英语听力软件 编辑:程序博客网 时间:2024/05/17 22:46

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 line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string. 
Output
There should be one line per test case containing the length of the largest string found. 
Sample Input
23ABCDBCDFFBRCD2roseorchid
Sample Output
22

 【题解】

  题意很简单,就是求m个串的最长公共子串,每个串可以正着也可以逆着,由于题目给的数据范围比较小,所以直接暴力求解;

 把第一个串的每一个子串当作目标串,每次遍历剩下的串,查找该子串(因为公共子串也一定在第一个串中),这里有技巧,那就是目标串从短到长递增遍历,这样如果某次长度为 i 的子串不能满足,那么长度>i 的肯定也找不到,所以这时候就直接更新答案然后退出就好了。

 因为每个串有正有逆,所以我们直接把正串和逆串都存起来,只要在其中一个找到目标串就可以了。

这里有个STL函数 strstr(s1,s2)表示在串1中查找串2,如果找到就返回其首元素下标值,否则返回null;

 有这个函数可以是代码更简洁,当然自己手写也是可以的。


这个题和我前几天做的一题做法类似,都是暴力枚举,推荐试试:POJ 3080



【AC代码】

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int N=105;int m,n;char str[N],s3[N];struct sstr{    char s1[N],s2[N]; //保存原串和原串的逆串}ss[N];int check() {    int ans=0;    int len3=strlen(s3);    for(int i=1;i<=len3;++i)//遍历长度为i的子串    {        bool tag=0;//标记剩下的m-1个串中是否找到长为i的串        for(int j=0;j<=len3-i;++j)//遍历长度为i的不同子串        {            int k=0;            int sk=j;            while(sk<i+j){            str[k++]=s3[sk++];//目标串            }            str[k]='\0';//注意  最好加上  否则有时候出bug却找不着  养成好习惯            int p=0;//标记剩下的m-1个串中是否有目标串            for(int l=1;l<m;++l)//遍历剩下的串            {                if((!strstr(ss[l].s1,str))&&(!strstr(ss[l].s2,str)))//查找子串                {                    p=1;//没找着就标记为1                    break;                }            }            if(p==0)//如果都找着了  就直接更新答案  退出            {                tag=1;                ans=i;                break;            }        }        if(!tag) break;//注意!!很重要的剪枝--如果长度为i的都没找着  那长度>i的一定也找不着    }    return ans;}int main(){    int t;    char str1[N];    scanf("%d",&t);    while(t--)    {        scanf("%d",&m);        for(int i=0;i<m;++i)        {            scanf("%s",str1);             if(!i)                strcpy(s3,str1);//以第一个串为根串            else{            strcpy(ss[i].s1,str1);//保存原串            reverse(str1,str1+strlen(str1)); //逆            strcpy(ss[i].s2,str1); //保存逆串            }        }        int ans=check();        reverse(s3,s3+strlen(s3));//根串求逆后再查找        ans=max(ans,check()); //保存最大值即答案        printf("%d\n",ans);    }    return 0;}



原创粉丝点击