L语言 bzoj-1212 HNOI-2004

题目大意:给你一个n个单词的集合,然后给你m条字符串。问每条字符串可以被理解的最长前缀。被理解当且仅当存在一种分割使得每一段都是集合里的元素。

注释:$1\le n,m\le 20$,长度不超过1M

想法:做了上一道,感觉这是个大水题... ...,我们将那个单词集合建立一个AC自动机,然后将每一个询问的字符串仍在字符串上跑,用bool型的dp。

dp[i]表示当前字符串前i位是否能被理解。

转移:如果j+1到i这段能被理解,那么dp[i]|=dp[j];

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 2000010
using namespace std;
char s[N];
int a[300][26];
bool end[300];
int n,m,cnt,fail[300],f[N];
void build(char *s)
{
int now=0;
int len=strlen(s);
for(int i=0;i<len;i++)
{
if(!a[now][s[i]-'a'])
{
a[now][s[i]-'a']=++cnt;
}
now=a[now][s[i]-'a'];
}
end[now]=true;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
build(s);
}
while(m--)
{
scanf("%s",s);
int l=strlen(s);
memset(f,0,sizeof f);
f[0]=1;
for(int i=0;i<l;i++)
{
if(f[i])
{
int now=0;
for(int j=i;a[now][s[j]-'a'];j++)
{
now=a[now][s[j]-'a'];
if(end[now])
{
f[j+1]|=f[i];
}
}
}
}
for(int i=l;~i;i--)
{
if(!f[i]) continue;
printf("%d\n",i);
break;
}
}
}

小结:ac自动接其实可以当Trie使.. ...虽然我写这东西是Trie图..

最新文章

  1. Java消息队列--ActiveMq 实战
  2. Java的垃圾回收和内存分配策略
  3. (一)Maven初步了解与认识
  4. 解剖SQLSERVER 第六篇 对OrcaMDF的系统测试里避免regressions(译)
  5. Nginx 配置详解
  6. 【转】Apache Options Indexes FollowSymLinks详解
  7. 在Linux里读取UBOOT环境变量
  8. (3)java棧
  9. SQLServer加入域后无法远程连接
  10. Code Snippet Library
  11. pcduino通过sd卡刷系统
  12. centos安装Chromium
  13. 在64位Win7操作系统中安装Microsoft Access Engine的解决方案
  14. codeforces 591B Rebranding (模拟)
  15. 使用Spring时web.xml中的配置
  16. OpenGL开发学习指南二(glfw+glad)
  17. boke练习: springboot整合springSecurity出现的问题,传递csrf
  18. jvm加载类(更新中)
  19. ALGO-139_蓝桥杯_算法训练_s01串(递归)
  20. phpunit 生成三种日志文件的配置方法

热门文章

  1. [BZOJ 1741] Asteroids
  2. 【POJ 3630】 Phone List
  3. jsp 常用标签的使用
  4. day-05 python函数
  5. Linux-防火墙设置-centos6.10版
  6. Spring-Boot配置文件数据源配置项
  7. 【专题】概率期望DP
  8. android开发 设备调试问题
  9. 最近积累的JS 东西,分享一下
  10. 自学Python五 爬虫基础练习之SmartQQ协议