#10053 L 语言
dalao 看来是水题?我可不这么认为。
很多人都写了我认为不怎么正确的贪心,那就是直接看到一个单词就减去。
那么这组数据就可以 hack 掉了:
2 1
whatis
what
whatisyourname
贪心法写出来是 \(4\) 但是答案为 \(6\)。
那怎么办?网上各路神仙有各种神仙做法,但是我选择了比较正常的 AC 自动机。
为什么是 AC 自动机:多模匹配不就是 AC 自动机模板吗。
具体方法如下:
- 正常建立 trie 图。
- 在插入的同时记录一个 \(depth_i\),表示节点 \(i\) 到根节点的距离。
- 根据每一个母串跑 AC 自动机,对于每一个节点,当匹配成功时立刻 break。
- 判断匹配成功的方法:
ed[j] && flag[i+1-depth[j]]。
可以发现,这里同样是类似于上面的贪心的立刻 break,但是这里的 AC 自动机是正确的,为什么?
同样是上面那组 hack 数据,当what判断后立刻 break,
之后到母串的whatis时,发现代表s的节点任然匹配成功,所以匹配了whatis。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
#include <queue>
#define N 30010
#define M 1000010
using namespace std;
int n, m, trie[N][30], fail[N], tot = 0, depth[N];
bool ed[N], flag[M];
char a[20], s[M];
void insert(char* a) {
int p = 0, len = strlen(a);
for (int i = 0; i < len; i++) {
int ch = a[i] - 'a';
if (!trie[p][ch]) {
trie[p][ch] = ++tot;
depth[tot] = depth[p] + 1;
}
p = trie[p][ch];
}
ed[p] = true;
return;
}
void get_fail() {
queue<int> q;
for (int i = 0; i < 26; i++)
if (trie[0][i]) {
fail[trie[0][i]] = 0;
q.push(trie[0][i]);
}
while (!q.empty()) {
int now = q.front();
q.pop();
for (int i = 0; i < 26; i++)
if (trie[now][i]) {
fail[trie[now][i]] = trie[fail[now]][i];
q.push(trie[now][i]);
} else
trie[now][i] = trie[fail[now]][i];
}
return;
}
int AC_work(char* a) {
memset(flag, false, sizeof(flag));
flag[0] = true;
int p = 0, len = strlen(a);
for (int i = 0; i < len; i++) {
p = trie[p][a[i] - 'a'];
for (int j = p; j; j = fail[j])
if (ed[j] && flag[i + 1 - depth[j]]) {//+1 是为了后面好统计。
flag[i + 1] = true;//+1 是为了后面好统计。
break;
}
}
for (int i = len; i; i--)
if (flag[i])
return i;
return 0;
}
int main() {
scanf("%d %d", &n, &m);
memset(ed, false, sizeof(ed));
for (int i = 1; i <= n; i++) {
scanf("%s", a);
insert(a);
}
get_fail();
for (int i = 1; i <= m; i++) {
scanf("%s", s);
printf("%d\n", AC_work(s));
}
return 0;
}
#10053 L 语言的更多相关文章
- 【Trie】L 语言
[题目链接]: https://loj.ac/problem/10053 [题意]: 给出n个模式串.请问文本串是由多少个模式串组成的. [题解]: 当我学完AC自动机后,发现这个题目也太简单了吧. ...
- BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]
1212: [HNOI2004]L语言 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1367 Solved: 598[Submit][Status ...
- 【BZOJ1212】[HNOI2004]L语言 Trie树
[BZOJ1212][HNOI2004]L语言 Description 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构 ...
- BZOJ 1212: [HNOI2004]L语言( dp + trie )
因为单词很短...用trie然后每次dp暴力查找...用哈希+dp应该也是可以的.... ------------------------------------------------------- ...
- [HNOI2004]Language L语言
2777: [HNOI2004]Language L语言 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 10 Solved: 5[Submit][S ...
- 1212: [HNOI2004]L语言
1212: [HNOI2004]L语言 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 643 Solved: 252[Submit][Status] ...
- 【BZOJ1212】L语言(AC自动机)
[BZOJ1212]L语言(AC自动机) 题面 BZOJ 题解 很自然的,既然要匹配单词,那就全部都丢到\(AC\)自动机里面去 现在想想怎么匹配 先是\(AC\)自动机正常的匹配 如果此时这个位置能 ...
- BZOJ_1212_[HNOI2004]L语言_哈希
BZOJ_1212_[HNOI2004]L语言_哈希 Description 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写 ...
- 洛谷 P2292 [HNOI2004] L语言 解题报告
P2292 [HNOI2004] L语言 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章\(T\)是由若干小写字母构成.一个单词 ...
随机推荐
- P2783 有机化学之神偶尔也会作弊 题解
题面 前言 这道题以前还是道(水)黑题,现在怎么降紫了???? 前置芝士 tarjain 缩点 倍增求LCA或树剖求LCA 脑子... 题意 给你一个无向图,要求你把所有的环缩成一个点.在新得到的图上 ...
- 设备通讯——RS232
RS232的接口有两种--一种公头.一种母头,两种头的引脚是有区别的 MAX232电路图: 注意:串口通讯需要交叉接线.
- ansible-playbook模板化(jinja2)
1. ansible-playbook模板化(jinja2)条件与循环 1.1) jinja使用结构图 2. 编写jinja2的循环 2.1) 编写jinja2模板 1 [root@test-1 ...
- 多测师讲解html _无序列表006_高级讲师肖sir
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>无 ...
- 慕课网go语言体系课抢先体验
慕课网go语言体系课抢先体验,课程分四个阶段: <第一阶段go语言基础语法篇>,从go语言基础语法篇讲起,go语言环境集成,常用开发工具集成,常用数据类型讲解,流程控制,函数,结构体,方法 ...
- Java第一课!
public class Text { public static void main(String[] args) { int a=100; //赋值a=100 System.out.println ...
- 【并查集】BZOJ 1854 连续攻击游戏
题目内容 洛谷链接 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的某一个属性.并 ...
- python 爬虫 循环分页
import osfrom time import sleepimport fakerimport requestsfrom lxml import etreefake = faker.Faker() ...
- TimeSpan时间间隔详解
1 public string GetShiXian(string fadanshijian) 2 { 3 string result,chulishijian; 4 5 DateTime fdTim ...
- c++ 获取文件创建时间、修改时间、访问时间、文件内容长度
int GetFileInfo(string& strPath, int& iCreateTime, int& iModifyTime, int& iAccessTim ...