【链接】http://acm.hdu.edu.cn/showproblem.php?pid=4763
【题意】给个字符串,求满足形如“E...E...E”这种鬼样子的E串最大长度,其中“...”可以是任意个数的任意字符(没有也ok),但是三个E之间不能重叠
【思路】
无视中间那个“E”的话,其实是在求前后缀相同的最大缀长
回头看一眼刚刚写完的poj 2752,终于知道为什么搜题解的路上会搜到这个了【喂
在找满足“E...E”这样的E串长度时,加个【长度 * 3 <= 总长】的特判的话,所有E串长度就都在手了
从最大长度开始找,把中间的“...”看做kmp的被查找串
E的长度为x的话就是从串s[x]~s[len-x-1]中找E
next数组不用动~
找之,有了就over,全部E串长找完了都没有就是0
什么?kmp算法是怎么实现的?我没说过我之前就有模板了吗?
听说有O(n)的算法的,像我这种随遇而安A了就好的人才不会去关心呢【滚
【代码】拿poj2752改的,结果忘记改数组大小还越界了次……
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define MAX_LEN 1000005
#define ll long long
#define mod 100000007
#define MEM(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define getArray(a,len) for(int ia = 0; ia < len; ia++) scanf("%d",&a[ia])
#define printArray(a,len) for(int ia = 0; ia < len; ia++) printf("%d%c",a[ia],(ia==len-1)?'\n':' ')
#define fora(i,n) for(i = 0; i < n; i++)
#define fora1(i,n) for(i = 1; i <= n; i++)
#define foraf(i,n) for(int i = 0; i < n; i++)
#define foraf1(i,n) for(int i = 1; i <= n; i++)
#define ford(i,n) for(i = n-1; i >= 0; i--)
#define ford1(i,n) for(i = n; i > 0; i--)
#define fordf(i,n) for(int i = n-1; i >= 0; i--)
#define fordf1(i,n) for(int i = n; i > 0; i--)
class WriteInfo{
public:
void info() { printf("[Info] "); }
void infoEnd() { printf(" [/Info]\n"); }
} W;
const int INF = 1<<29;
const double INFD = 1e20;
const double eps = 1e-6;
int n,m,len;
char s[MAX_LEN];
int next[MAX_LEN];
int res[MAX_LEN];
void getNext(){
MEM(next,-1);
int j = -1;
foraf1(i, len-1){
while(j > -1 && s[i] != s[j+1]) j = next[j];
if (s[i] == s[j+1]) j++;
next[i] = j;
}
}
bool kmp(int x){
int j = -1;
for(int i = x; i < len - x; i++){
while(j > -1 && s[i] != s[j+1]) j = next[j];
if (s[i] == s[j+1]) j++;
if (j == x-1) return true;
}
return false;
}
int main() {
int i,j,k;
int T;
sdx(T);
while(T--){
scanf("%s",s);
len = strlen(s);
getNext();
i = len-1;
j = 0;
while(next[i] != -1){
if ( (next[i]+1)*3 <= len) res[j++] = next[i]+1;
i = next[i];
}
sort(res,res+j);
// 缀长为res[i],降序
bool flag = false;
fordf(i,j){
if (kmp(res[i])){
pdx(res[i]);
flag = true;
break;
}
}
if (!flag) pdx(0);
}
return 0;
}
虽然能手打kmp了但我相信我一定是没有理解的-_,-,算了算了回家吃饭……