1. 程式人生 > >Theme Section HDU - 4763(些許暴力)

Theme Section HDU - 4763(些許暴力)

using map sin 匹配 mes sign lse ctype theme

題意:

  求出最長公共前後綴 不能重疊 而且 這個前後綴 在串的中間也要出現一次

解析:

  再明確一次next數組的意思:完全匹配的最長前後綴長度

  求一遍next 然後暴力枚舉就好了

  

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include 
<stack> #include <queue> #include <algorithm> #include <cmath> #define rap(i, a, n) for(int i=a; i<=n; i++) #define rep(i, a, n) for(int i=a; i<n; i++) #define lap(i, a, n) for(int i=n; i>=a; i--) #define lep(i, a, n) for(int i=n; i>a; i--) #define rd(a) scanf("%d", &a) #define
rlld(a) scanf("%lld", &a) #define rc(a) scanf("%c", &a) #define rs(a) scanf("%s", a) #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin);
using namespace std; const int maxn = 1e6+10, INF = 0x7fffffff; int nex[maxn]; void get_next(char *s) { int len = strlen(s); int j = 0, k = -1; nex[0] = -1; while(j < len) { if(k == -1 || s[j] == s[k]) nex[++j] = ++k; else k = nex[k]; } } int kmp(char *s, char *t, int len1, int len2) //串1 串2 串1的長度 串2的長度 { int i, j = 0; if(len1 == 1 && len2 == 1) { if(s[0] == t[0]) return true; else return false; } for(int i=0; i<len1; i++) { while(j > 0 && s[i] != t[j]) j = nex[j]; if(s[i] == t[j]) j++; if(j == len2) return true; } } char s[maxn]; char s2[maxn]; int main() { int T; rd(T); while(T--) { rs(s); get_next(s); int len = strlen(s); if(!nex[len]){ cout<< "0" <<endl; } else { int tmp = nex[len]; while(tmp) { if(tmp*3 > len) //如果當前長度大於三倍 那麽就用次長來匹配 { tmp = nex[tmp]; continue; } for(int i=0; i<tmp; i++) //暴力取出那段子串 s2[i] = s[i]; if(kmp(s+tmp, s2, len - 2*tmp, tmp)) { cout<< tmp <<endl; break; } tmp = nex[tmp]; } } } return 0; }

Theme Section HDU - 4763(些許暴力)