HDU 4763 Theme Section(KMP)
阿新 • • 發佈:2018-11-01
【連結】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了但我相信我一定是沒有理解的-_,-,算了算了回家吃飯……