Tire树是一种基于空间换时间思想的,应用于字符串处理的数据结构。
分析:设DP数组Can[MaxL],Can[i]=1表示第i位可以理解。
当Can[i]==1,对第i+1位进行匹配,若能匹配完整的单词,那么也是可以理解的。
另外注意使用getline会读进来一些奇怪的东西。
#include <stdio.h> #include <string.h> #define re register #define GC getchar() #include <string> #define Clean(X,K) memset(X,K,sizeof(X)) #include <iostream> #define Max(A,B) (A>B?A:B) using namespace std ; int Qread () { int X = 0 ;char C = GC ; while (C > ‘9‘ || C < ‘0‘) C = GC ; while (C >=‘0‘ && C <=‘9‘) { X = X * 10 + C - ‘0‘ ; C = GC ; } return X ; } const int Maxn = 22 , MaxL = 12 , Base = 26 , INF = 20021020 << 2; int N , M, T[Maxn * MaxL][Base] , Tot = 0 , End[Maxn * MaxL] , Can[1000000] , Len , Ans = 0; string S ; void Add () { int P = 0 , L = S.length() ; for (re int i = 0 ; i < L; ++ i) { if (!T[P][S[i]-‘a‘]) T[P][S[i]-‘a‘] = ++ Tot ; P = T[P][S[i] - ‘a‘] ; } End[P] = INF ; } void Ask (int From ) { int P = 0 ; for (re int i = From ; i < Len ; ++ i) { if (!T[P][S[i] - ‘a‘]) return ; P = T[P][S[i] - ‘a‘] ; if (End[P]) { Can[i] = INF ; Ans = Max (Ans , i + 1); } } } int main () { // freopen ("P2292.in" , "r" , stdin) ; N = Qread () , M = Qread () ; Clean (T , 0) , Clean (End , 0); for (re int i = 0 ; i < N; ++ i) { cin >> S ; Add () ; } for (re int i = 0 ; i < M; ++ i) { cin >> S ; Clean (Can , 0) , Ans= 0, Len = S.length() ; Ask (0) ; for (re int j = 0 ; j < Len ;++ j) if (Can[j]) Ask (j + 1) ; printf ("%d\n" , Ans) ; } fclose (stdin) , fclose (stdout) ; return 0 ; }
原文:https://www.cnblogs.com/bj2002/p/10589309.html