#trie,动态规划#洛谷 2292 [HNOI2004]L语言

题目


分析

建一棵trie,然后匹配最长前缀可以用\(dp\)做,
如果这个位置可以被匹配到那么可以从这个位置继续匹配


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
int trie[211][26],n,m,Tot,endd[211];
char s[1000011]; bool v[1000011];
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
signed main(){
	scanf("%d%d",&n,&m),Tot=1;
	for (rr int i=0;i<26;++i) trie[0][i]=1;
	for (rr int i=1;i<=n;++i){
		rr int p=1; rr char c=getchar(),s[11],len=0;
		while (!isalpha(c)) c=getchar();
		while (isalpha(c)) s[++len]=c,c=getchar();
		for (rr int j=1;j<=len;++j){
			rr int x=s[j]-97;
			if (!trie[p][x]) trie[p][x]=++Tot;
			p=trie[p][x];
		}
		endd[p]=1;
	}
	while (m--){
		rr char c=getchar(); rr int len=0,ans=0;
		while (!isalpha(c)) c=getchar();
		while (isalpha(c)) s[++len]=c,c=getchar();
		memset(v,0,sizeof(v)),v[0]=1;
		for (rr int i=0;i<=len;++i)
		if (v[i]){
			ans=i;
			for (rr int j=i+1,p=1;j<=len;++j){
				p=trie[p][s[j]-97];
				if (!p) break;
				if (endd[p]) v[j]=1;
			}
		}
		print(ans),putchar(10);
	}
	return 0;
}
posted @ 2020-08-18 21:02  lemondinosaur  阅读(85)  评论(0编辑  收藏  举报