POJ 1226 Substrings(最长公共连续串的变形,可以倒转+KMP)
来源:互联网 发布:网络协议实践 李毅超 编辑:程序博客网 时间:2024/06/08 05:52
Substrings
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 10451 Accepted: 3598
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 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
题目大意:给你n个串,求最小公共连续子串,不过这个可以倒转,比如ro和or可以匹配
解题思路:思路很清晰,把第一个串当模式串,分解求next匹配然后逆转求next匹配。自己的思路是先顺序找到子串,然后再找它的逆转串的相对位置。例如模式串abcdefg,我先逆转模式串放在另一个数组里面。子串可以是bcde(sta=1,len=1+4)逆转就变成了edcb(sta=7-1-4,len=7-1).这样把规律看出来就可以了。果断一A!
题目地址:Substrings
AC代码:
#include<iostream>#include<cstring>#include<string>#include<cstdio>using namespace std;int nextp[105],nexts[105],n;char a[105][105];char b[105]; //将模式串翻转int lena0; //模式串的长度//我的思路是用第一个字符串当模式串,然后再枚举长度由大到小求next匹配void getnextp(int sta,int len) //模式串{ int i,j; len=sta+len; //相对位置变成绝对位置 nextp[sta]=sta,nextp[sta+1]=sta; for(i=sta+1;i<len;i++) { j=nextp[i]; while(j!=sta&&a[0][i]!=a[0][j]) j=nextp[j]; if(a[0][i]==a[0][j]) nextp[i+1]=j+1; else nextp[i+1]=sta; }}void getnexts(int sta,int len) //翻转后的模式串{ int i,j; sta=lena0-sta-len; //要把子串的位置转换成b的位置 len=sta+len; nexts[sta]=sta,nexts[sta+1]=sta; for(i=sta+1;i<len;i++) { j=nexts[i]; while(j!=sta&&b[i]!=b[j]) j=nexts[j]; if(b[i]==b[j]) nexts[i+1]=j+1; else nexts[i+1]=sta; }}int KMP(int sta,int len){ int i,j,k; int sta1=sta; int sta2=lena0-sta-len; int len1=sta+len; int len2=sta2+len; for(k=1;k<n;k++) //后面的串都和第一个串的子串匹配 { int flag=0; j=sta1; for(i=0;i<strlen(a[k]);i++) { while(j!=sta1&&a[k][i]!=a[0][j]) j=nextp[j]; if(a[k][i]==a[0][j]) j++; if(j==len1) { flag=1; break; } } j=sta2; for(i=0;i<strlen(a[k]);i++) { while(j!=sta2&&a[k][i]!=b[j]) j=nexts[j]; if(a[k][i]==b[j]) j++; if(j==len2) { flag=1; break; } } if(flag==0) //有一个没有匹配,便返回0 return 0; } return 1;}int main(){ int i,j,T,l; scanf("%d",&T); while(T--) { scanf("%d",&n); if(n==0) break; for(i=0;i<n;i++) scanf("%s",a[i]); lena0=strlen(a[0]); for(i=0;i<lena0;i++) b[i]=a[0][lena0-i-1]; b[lena0]='\0'; int flag=0; for(i=lena0;i>=1;i--) //从长度lena0开始往下枚举 { int flag1=0; //长度为i的是否存在 for(j=0;j<=lena0-i;j++) //模式串分解的起始位置 { getnextp(j,i); getnexts(j,i); if(KMP(j,i)) { flag1=1; printf("%d\n",i); break; } } if(flag1) { flag=1; break; } } if(flag==0) puts("0"); } return 0;}
- POJ 1226 Substrings(最长公共连续串的变形,可以倒转+KMP)
- HDU1238 Substrings(kmp,最长公共子串)
- POJ 1226 Substrings (后缀数组 n个串的最长公共子串)
- poj 1080 最长公共子串变形
- poj 3356 最长公共子串变形
- POJ 3080 Blue Jeans(KMP:最长连续公共子序列)
- POJ 3450 Corporate Identity(KMP:最长连续公共子序列)
- 【KMP求多个串的最长公共子串】POJ 3450
- poj--3450 KMP求多个字符串的最长公共子串
- POJ 1226 Substrings KMP
- 两个字符串的最长公共子序列(可以不连续)
- POJ 1226 Substrings(KMP+枚举)
- poj 1226 hdu 1238 Substrings 求若干字符串正串及反串的最长公共子串 2002亚洲赛天津预选题
- POJ 2774 找出2字符串 最长公共连续子串
- 【KMP多串最长公共子串】POJ 3080
- POJ 3080 查找公共最长子串 kmp+枚举
- poj 3450 Corporate Identity (KMP+最长公共子串)
- poj 3080 Blue Jeans (KMP+最长公共子串)
- Android游戏开发:游戏框架的搭建(4)
- hdu 1561 树形DP
- 借助C3P0连接池访问dept表
- MySQL两种常用的存储引擎(mysql调优)
- 小谈 MD5加密算法
- POJ 1226 Substrings(最长公共连续串的变形,可以倒转+KMP)
- nginx负载均衡器处理session共享的几种方法
- c++写dll文件,用delphi stdcall调用报地址000001错误,
- ubuntu server sudo出现sudo:must be setuid root 完美解决办法。
- 序言
- ubuntu下minizip的环境配置
- Win2003单网卡创建vpn连接
- tomcat无法正常启动
- spider技术综述