HDU 1238 Substrings

Substrings

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5654 Accepted Submission(s): 2487


Problem 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 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

Author
Asia 2002, Tehran (Iran), Preliminary


/*
  用string类型保存字符串,边读入的时候边找到最短的一个字符串
  因为最大的重复字串长度最长也不可能最短的字符串长度
  所以只需枚举最短的字符串的子串,判断是否都是别的字符串的子串,
  求出最大长度即可

  用到了string.find  和  string.rfind
*/

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<string>
#include<iterator>
using namespace std;
int main (void)
{
    int T , n;
    int i , j, k;
    scanf("%d", &T);
    while(T--)
    {
        int count = 0;
        int min = 100000;
        int len;
        int flag;
        vector<string>s;
        s.clear();
        scanf("%d", &n);
        for(i = 0; i < n; i++)
        {
            string temp;
            cin >> temp;
            len = temp.size();
            if(min > len) {min = len; flag = i;}
            s.push_back(temp);

        }

        for(i = s[flag].size(); i > 0; i--) //从最小的母串开始从长到短找子串
            for(j = 0; j <= s[flag].size() - i; j++) //长度为i的子串在母串中找
            {

                string temp1, temp2;  //用temp1来保存字串 temp2来保存字串的反串
                temp1 = s[flag].substr(j, i);
                temp2 = temp1; 
                reverse(temp2.begin(),temp2.end());   //将temp2 反串
                for(k = 0; k < n; k++)
                {
                    if(k == flag)  continue;
                    if(s[k].find(temp1) == string::npos && s[k].rfind(temp2)) //当正反子串在母串中都未发现时即跳出
                        break;
                }
                if(k == n   &&   count < temp1.size())
					   count = temp1.size();
				 
            }

            printf("%d\n", count);
    }
    return 0;
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值