M - Substrings (KMP ——暴力枚举)

M - Substrings

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

2
3
ABCD
BCDFF
BRCD
2
rose
orchid

Sample Output

2
2

题意:

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

思路:

             KMP + 字符串枚举

注意:

            1)数组范围,开小了会 WR (WR了3次的我。。。)

             2)反转函数   reverse(str.begin(),str.end());   —— 反转str这个字符串

相似题: 

              I - Blue Jeans   、N - Corporate Identity

代码:

           

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MM 105
#define mem(a,b) memset(a,b,sizeof(a))
int ne[MM];
void Getne(string mo)
{
    mem(ne,0);
    int i=0,j=-1,lm=mo.size();
    ne[0]=-1;
    while(i<lm)
    {
        while(j!=-1&&mo[i]!=mo[j])
            j=ne[j];
        ne[++i]=++j;
    }
}
bool KMP(string mo,string text)
{
    int i=0,j=0,lm=mo.size(),lt=text.size();
    Getne(mo);
    while(i<lt)
    {
        while(j!=-1&&text[i]!=mo[j])
            j=ne[j];
        i++,j++;
        if(j>=lm)
            return true;
    }
    return false;
}
int main()
{
   int ca;
   scanf("%d",&ca);
   while(ca--)
   {
       string str[105];         //数组范围
       int n,i,j,k;
       scanf("%d",&n);
       for(i=0;i<n;i++)
       {
           cin>>str[i];
       }
       string ans,w,w1;
       bool flag=0;
       int ls0=str[0].size();
       for(i=0;i<ls0;i++)
       {
           for(j=i;j<ls0;j++)
           {
               w=str[0].substr(i,j-i+1);
               w1=w;
               reverse(w1.begin(),w1.end());         //反转子串
               for(k=1;k<n;k++)
               {
                   if(!KMP(w,str[k])&&!KMP(w1,str[k]))     //两个都不满足
                    break;
               }
               if(k>=n)
               {
                   if(w.size()>ans.size())
                    ans=w;
               }
           }
       }
    cout<<ans.size()<<endl;
   }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/team39/article/details/81126913