HDU 1238 Substrings(KMP+暴力枚举)
2017-08-21 17:04
387 查看
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.
InputThe 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.
OutputThere should be one line per test case containing the length of the largest string found.
Sample Input
Sample Output
【题解】
题意很简单,就是求m个串的最长公共子串,每个串可以正着也可以逆着,由于题目给的数据范围比较小,所以直接暴力求解;
把第一个串的每一个子串当作目标串,每次遍历剩下的串,查找该子串(因为公共子串也一定在第一个串中),这里有技巧,那就是目标串从短到长递增遍历,这样如果某次长度为 i 的子串不能满足,那么长度>i 的肯定也找不到,所以这时候就直接更新答案然后退出就好了。<
4000
/p>
因为每个串有正有逆,所以我们直接把正串和逆串都存起来,只要在其中一个找到目标串就可以了。
这里有个STL函数 strstr(s1,s2)表示在串1中查找串2,如果找到就返回其首元素下标值,否则返回null;
有这个函数可以是代码更简洁,当然自己手写也是可以的。
这个题和我前几天做的一题做法类似,都是暴力枚举,推荐试试:POJ 3080
解题博客:http://blog.csdn.net/qq_38538733/article/details/77278363
【AC代码】
InputThe 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.
OutputThere 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个串的最长公共子串,每个串可以正着也可以逆着,由于题目给的数据范围比较小,所以直接暴力求解;
把第一个串的每一个子串当作目标串,每次遍历剩下的串,查找该子串(因为公共子串也一定在第一个串中),这里有技巧,那就是目标串从短到长递增遍历,这样如果某次长度为 i 的子串不能满足,那么长度>i 的肯定也找不到,所以这时候就直接更新答案然后退出就好了。<
4000
/p>
因为每个串有正有逆,所以我们直接把正串和逆串都存起来,只要在其中一个找到目标串就可以了。
这里有个STL函数 strstr(s1,s2)表示在串1中查找串2,如果找到就返回其首元素下标值,否则返回null;
有这个函数可以是代码更简洁,当然自己手写也是可以的。
这个题和我前几天做的一题做法类似,都是暴力枚举,推荐试试:POJ 3080
解题博客:http://blog.csdn.net/qq_38538733/article/details/77278363
【AC代码】
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int N=105; int m,n; char str ,s3 ; struct sstr { char s1 ,s2 ; //保存原串和原串的逆串 }ss ; 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 ; 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; }
相关文章推荐
- HDU 1238 Substrings(KMP+暴力枚举)
- (HDU)1238 - Substrings 【KMP枚举】or【String】
- hdu 1238 Substrings(暴力枚举)
- hdu 1238 Substrings(暴力枚举)
- HDU 1238 Substrings(KMP)
- HDU-1238 - Substrings - KMP
- POJ 1226 && HDU 1238 Substrings(kmp)
- hdu 1238 Substrings (暴搜,枚举)
- hdu 1238 Substrings (暴搜,枚举)
- HDU 1238 Substrings (暴力)
- hdu_2328_Corporate Identity(暴力枚举子串+KMP)
- HDU1238_搜索入门_暴力枚举
- hdu1238 Substrings 扩展KMP
- hdu 1238 Substrings 字符串暴力
- hdu 1238 Substrings(KMP)
- poj 1226|| hdu 1238 Substrings(KMP)
- hdu 1238 KMP+枚举
- hdu 1238 暴力枚举+STL
- poj1226 Substrings (应该用kmp,但是数据弱,暴力枚举就行了)
- Substrings HDU - 1238 (kmp+暴力枚举)