acwing算法提高之数据结构--AC自动机

目录

  • 1 介绍
  • 2 训练
  • 3 参考

1 介绍

本博客用来记录AC自动机相关题目。

AC自动机是以Trie的结构为基础,结合KMP的思想建立的自动机,用于解决多模式匹配等任务。

2 训练

题目1:1282搜索关键词

C++代码如下,

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 10010, S = 55, M = 1000010;int n;
int tr[N*S][26], cnt[N*S], idx;
char str[M];
int q[N*S], ne[N*S];void insert() {int p = 0;for (int i = 0; str[i]; ++i) {int t = str[i] - 'a';if (!tr[p][t]) tr[p][t] = ++idx;p = tr[p][t];}cnt[p]++;
}void build() {int hh = 0, tt = -1;for (int i = 0; i < 26; ++i) {if (tr[0][i]) {q[++tt] = tr[0][i];}}while (hh <= tt) {int t = q[hh++];for (int i = 0; i < 26; ++i) {int p = tr[t][i];if (!p) tr[t][i] = tr[ne[t]][i];else {ne[p] = tr[ne[t]][i];q[++tt] = p; }}}
}int main() {int T;scanf("%d", &T);while (T--) {memset(tr, 0, sizeof tr);memset(cnt, 0, sizeof cnt);memset(ne, 0, sizeof ne);idx = 0;scanf("%d", &n);for (int i = 0; i < n; ++i) {scanf("%s", str);insert();}build();scanf("%s", str);int res = 0;for (int i = 0, j = 0; str[i]; ++i) {int t = str[i] - 'a';j = tr[j][t];int p = j;while (p) {res += cnt[p];cnt[p] = 0;p = ne[p];}}printf("%d\n", res);}return 0;
}

用string类型的find()函数的暴力写法,通过了 12/13个数据,

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>using namespace std;int main() {int T;cin >> T;while (T--) {int n;cin >> n;vector<string> words(n);for (int i = 0; i < n; ++i) cin >> words[i];string article;cin >> article;int res = 0;for (auto word : words) {if (article.find(word) != string::npos) res++;}cout << res << endl;}return 0;
}

题目2:1285单词

C++代码如下,

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 1000010;int n;
int tr[N][26], f[N], idx;
int q[N], ne[N];
char str[N];
int id[210];void insert(int x) {int p = 0;for (int i = 0; str[i]; i++) {int t = str[i] - 'a';if (!tr[p][t]) tr[p][t] = ++idx;p = tr[p][t];f[p]++;}id[x] = p;
}void build() {int hh = 0, tt = -1;for (int i = 0; i < 26; ++i) {if (tr[0][i]) {q[++tt] = tr[0][i];}}while (hh <= tt) {int t = q[hh++];for (int i = 0; i < 26; ++i) {int &p = tr[t][i];if (!p) p = tr[ne[t]][i];else {ne[p] = tr[ne[t]][i];q[++tt] = p;}}}
}int main() {scanf("%d", &n);for (int i = 0; i < n; ++i) {scanf("%s", str);insert(i);}build();for (int i = idx - 1; i >= 0; --i) f[ne[q[i]]] += f[q[i]];for (int i = 0; i < n; ++i) printf("%d\n", f[id[i]]);return 0;
}

使用kmp来做,超时了,通过了 9/11个数据

#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>using namespace std;void kmp(string &pattern_str, string &match_str) {//cout << "pattern_str = " << pattern_str << ", match_str = " << match_str << endl;int n = pattern_str.size();int m = match_str.size();pattern_str = '#' + pattern_str;match_str = '$' + match_str;//求取next数组nevector<int> ne(n + 10, 0);for (int i = 2, j = 0; i <= n; ++i) {while (j && pattern_str[i] != pattern_str[j+1]) j = ne[j];if (pattern_str[i] == pattern_str[j+1]) j++;ne[i] = j;}//返回匹配的下标位置vector<int> idxs; //匹配串match_str中的下标位置,表示从改下标起,与模式串pattern_str匹配for (int i = 1, j = 0; i <= m; ++i) {while (j && match_str[i] != pattern_str[j+1]) j = ne[j];if (match_str[i] == pattern_str[j+1]) j++;if (j == n) {//cout << i - n << " ";idxs.emplace_back(i-n);j = ne[j];}}// for (int idx : idxs) {//     cout << idx << " ";// }// cout << endl;cout << idxs.size() << endl;pattern_str = pattern_str.substr(1);match_str = match_str.substr(1);return;
}int main() {int n;cin >> n;vector<string> words(n);for (int i = 0; i < n; ++i) cin >> words[i];string article;for (auto word : words) article += word + "?";for (auto word : words) {kmp(word, article);}return 0;
}

题目3:1053修复DNA

C++代码如下,

#include <iostream>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 1010;int n, m;
int tr[N][4], dar[N], idx;
int q[N], ne[N];
char str[N];int f[N][N];int get(char c) {if (c == 'A') return 0;if (c == 'T') return 1;if (c == 'G') return 2;return 3;
}void insert() {int p = 0;for (int i = 0; str[i]; ++i) {int t = get(str[i]);if (tr[p][t] == 0) tr[p][t] = ++idx;p = tr[p][t];}dar[p] = 1;
}void build() {int hh = 0, tt = -1;for (int i = 0; i < 4; ++i) {if (tr[0][i]) {q[++tt] = tr[0][i];}}while (hh <= tt) {int t = q[hh++];for (int i = 0; i < 4; ++i) {int p = tr[t][i];if (!p) tr[t][i] = tr[ne[t]][i];else {ne[p] = tr[ne[t]][i];q[++tt] = p;dar[p] |= dar[ne[p]];}}}
}int main() {int T = 1;while (scanf("%d", &n), n) {memset(tr, 0, sizeof tr);memset(dar, 0, sizeof dar);memset(ne, 0, sizeof ne);idx = 0;for (int i = 0; i < n; ++i) {scanf("%s", str);insert();}build();scanf("%s", str + 1);m = strlen(str + 1);memset(f, 0x3f, sizeof f);f[0][0] = 0;for (int i = 0; i < m; ++i) {for (int j = 0; j <= idx; ++j) {for (int k = 0; k < 4; ++k) {int t = get(str[i+1]) != k;int p = tr[j][k];if (!dar[p]) f[i+1][p] = min(f[i+1][p], f[i][j] + t);}}}int res = 0x3f3f3f3f;for (int i = 0; i <= idx; ++i) res = min(res, f[m][i]);if (res == 0x3f3f3f3f) res = -1;printf("Case %d: %d\n", T++, res);}return 0;
}

3 参考

AC自动机-OI Wiki

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/5582.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 HAL库F103系列之IIC实验

IIC总线协议 IIC总线协议介绍 IIC&#xff1a;Inter Integrated Circuit&#xff0c;集成电路总线&#xff0c;是一种同步 串行 半双工通信总线。 总线就是传输数据通道 协议就是传输数据的规则 IIC总线结构图 ① 由时钟线SCL和数据线SDA组成&#xff0c;并且都接上拉电阻…

[华为OD] C卷 5G网络 现需要在某城市进行5G网络建设,已经选取N个地点设置5G基站 200

题目 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N,接 下来需要各个基站之间使用光纤进行连接以确保基站能互联互通&#xff0c;不同基站之间架设光纤的成 本各不相同&#xff0c;且有些节点之间已经存在光纤相连&#…

try-catch-finally的省略与springboot

在 Java 中&#xff0c;try-catch 块是用于捕获和处理异常的结构&#xff0c;它可以帮助您在代码中处理可能发生的异常情况。在某些情况下&#xff0c;您可能希望省略 try-catch 块并将异常向上抛出&#xff0c;让调用者处理异常。这种情况通常适用于以下情况&#xff1a; 方法…

python项目入门新手攻略

最近工作需要接手了代码量比较大的python开发的项目&#xff0c;平时写python不多&#xff0c;记录一下如何熟悉项目。 分析调用流程-pycallgraph 因为代码量比较大&#xff0c;所以希望通过工具生成代码调用流程&#xff0c;因此用到了pycallgraph。 pycallgraph&#xff0…

boost::asio::ip::tcp::acceptor::reuse_address

boost::asio::ip::tcp::acceptor::reuse_address 是一个选项&#xff0c;用于设置 tcp::acceptor 对象是否可以在绑定到一个地址后立即重新使用该地址。 在网络编程中&#xff0c;当服务器程序关闭后&#xff0c;操作系统可能会保留 socket 使用的地址一段时间。在这段时间内&…

【AIGC调研系列】InternVL开源多模态模型与GPT-4V的性能对比

InternVL和GPT-4V都是多模态模型&#xff0c;但它们在性能、参数量以及应用领域上有所不同。 InternVL是一个开源的多模态模型&#xff0c;其参数量为60亿&#xff0c;覆盖了图像/视频分类、检索等关键任务&#xff0c;并在32个视觉-语言基准测试中展现了卓越性能[2]。InternV…

linux操作系统,进入救援模式的方法

准备好操作系统的 ISO 文件 或 刻录好的U盘启动盘 登录服务器 BMC 管理界面&#xff0c;选择镜像之后&#xff0c;点击 “启动媒体”&#xff08;如果使用U盘启动盘 则跳过这一步骤&#xff0c;直接看下一步&#xff09; 重启服务器&#xff0c;开机界面一般按键盘 “Delete”…

数据库管理工具

Heidisql HeidiSQL是一款简洁的图形化的数据库管理工具&#xff0c;支持MySQL、SQLServer、PostgreSQL、SQLite等多种数据库。HeidiSQL提供了一个用于在数据库浏览之间切换 SQL 查询和标签带有语法突出显示的简单易用的界面。其它功能包括BLOB 和 MEMO 编辑&#xff0c;大型SQ…

优雅处理枚举值映射和分页

文章目录 引言I pagehelper分页1.1 pagehelper配置1.2 使用方法1.3 SQLServerException: LIMIT 附近有语法错误。II mybatis-plus2.1 多数据源配置2.2 优雅处理枚举值映射@EnumValue2.3 配置枚举扫描包2.4 常见问题引言 分页效果 优雅处理枚举值映射

docker seata

docker pull seataio/seata-server:1.6.1 数据库脚本&#xff1a; incubator-seata/script/server/db at master apache/incubator-seata GitHub #先启动服务 docker run -d --name seata -p 8091:8091 -p 7091:7091 seataio/seata-server:1.6.1 #将配置文件拷贝出来 …

PotatoPie 4.0 实验教程(34) —— FPGA实现摄像头图像二值化腐蚀效果

链接直达 https://item.taobao.com/item.htm?ftt&id776516984361 图像二值化腐蚀处理有什么作用&#xff1f; 图像二值化腐蚀处理在图像处理中起到了以下作用&#xff1a; 物体分割与提取&#xff1a;在图像二值化之后&#xff0c;通过腐蚀操作可以消除噪声、连接相邻的…

【C语言】动态内存分配

即使行动导致错误&#xff0c;却也带来了学习与成长;不行动则是停滞与萎缩。&#x1f493;&#x1f493;&#x1f493; 目录 •&#x1f319;知识回顾 &#x1f34b;知识点一&#xff1a;为什么要有动态内存分配 &#x1f34b;知识点二&#xff1a;malloc和free • &#x1…

shell脚本,删除30天以前的日志,并将日志推送到nas,但运行出现/bin/bash^M。

删除30天以前的日志 将日志推送到nas中&#xff0c;然后删除pod中的日志 pod挂载到本地 运行出现/bin/bash^M 1、删除30天以前的日志&#xff1a; #! /bin/bash# 定义源日志目录 LOG_DIR/home/log/ # 删除日志 find $LOG_DIR -type f -name "*.log" -mtime 30 -exec…

持续总结中!2024年面试必问 100 道 Java基础面试题(二十二)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 100 道 Java基础面试题&#xff08;二十一&#xff09;-CSDN博客 四十三、String属于基础的数据类型吗&#xff1f; 在Java中&#xff0c;String不属于基础数据类型&#xff08;也称为原始数据类型或内置数据类型…

2024年五一杯高校数学建模竞赛(C题) 建模解析| 冲击地压危险预测 |小鹿学长带队指引全代码文章与思路

我是鹿鹿学长&#xff0c;就读于上海交通大学&#xff0c;截至目前已经帮200人完成了建模与思路的构建的处理了&#xff5e; 本篇文章是鹿鹿学长经过深度思考&#xff0c;独辟蹊径&#xff0c;通过滑动平均法解决冲击地压危险预测问题。实现综合建模。独创复杂系统视角&#xf…

GPU系列(三):如何管理GPU

1 使用nvidia-smi管理你的GPU卡 nvidia-smi命令是NVIDIA系统管理接口&#xff0c;之前提到使用nvidia-docker实际上底层也是调用的该接口。该接口可以查看到当前主机上的相关GPU设备&#xff0c;任务以及当前状态等信息&#xff0c;熟练使用该接口能够更好的管理好GPU系统资源…

在做题中学习(48):朴素的二分查找

. - 力扣&#xff08;LeetCode&#xff09; 解法一&#xff1a; 暴力求解 for循环中&#xff0c;从nums[0]枚举到nums[n-1]&#xff0c;依次判断&#xff0c;返回 target的值。 时间复杂度 : O(N) :因为要遍历一遍数组 解法二&#xff1a;二分查找 因为此数组为有序的…

Mybatis进阶(动态SQL)

文章目录 1.动态SQL1.基本介绍1.为什么需要动态SQL2.基本说明3.动态SQL常用标签 2.环境搭建1.新建子模块2.删除不必要的两个文件夹3.创建基本结构4.父模块的pom.xml5.jdbc.properties6.mybatis-config.xml7.MyBatisUtils.java8.MonsterMapper.java9.MonsterMapper.xml10.测试Mo…

如何将安卓手机投屏到Windows 10电脑上

诸神缄默不语-个人CSDN博文目录 我之所以要干这个事是为了用手机直播的时候在电脑上看弹幕…… 文章目录 1. 方法一&#xff1a;直接用Win10内置的投影到此电脑2. 方法二&#xff1a;用AirDroid Cast投屏到电脑上 1. 方法一&#xff1a;直接用Win10内置的投影到此电脑 在设置…

C++ 多态详解

文章目录 1. 多态的概念2. 多态的定义及实现2.1 多态的构成条件2.2 虚函数2.3 虚函数的重写2.3.1 虚函数重写的两个例外 2.4 C11 override 和 final2.5 重载、覆盖(重写)、隐藏(重定义)的对比 3. 多态的原理3.1 虚函数表3.2多态的原理 4. 单继承和多继承关系的虚函数表4.1 单继…