博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AC自动机妙用
阅读量:5144 次
发布时间:2019-06-13

本文共 2578 字,大约阅读时间需要 8 分钟。

理解题意之后,很自然的想到了用AC自动机搞,结果网上一搜,全是暴搜,按照自己的思想,AC自动机搞起,果然在提交了数次之后,看到了Accept。

AC自动机需要三个步骤:

第一步:建立字典树;

第二步:为字典树建立 Fail 指针 ;

第三步:进行匹配;

#include
#include
#include
#include
#include
#include
#define max(x,y) ((x) > (y) ? (x) : (y))using namespace std ;struct Node { Node *next[26] ; Node *fail ; bool is_over ; int len ;};Node* new_node() { Node *root = new Node ; root ->fail = NULL ; for(int i = 0 ; i< 26 ; i++) root->next[i] = NULL ; root ->is_over = false ; return root ;}void build_tree( Node *root , char *s ) { int len = strlen(s) ; for(int i = 0 ; i < len ; i++) { if(root->next[s[i] - 'a'] == NULL) root->next[s[i] - 'a'] = new_node() ; root = root ->next[s[i] - 'a'] ; } root ->is_over = true ; root ->len = len ;}void build_fail(Node *root) { Node *r = root ; queue< Node* > q ; q.push(root) ; while(!q.empty()) { r = q.front() ; q.pop() ; Node *p = r ; for(int i = 0 ; i < 26 ; i++) { if(p->next[i] != NULL) { if(p == root) { p->next[i]->fail = root ; q.push(p->next[i]) ; continue ; } while(r->fail->next[i] == NULL && r ->fail != root) r = r->fail ; if(r->fail ->next[i] != NULL) p ->next[i]->fail = r ->fail ->next[i] ; else p ->next[i] ->fail = root ; q.push(p->next[i]) ; } } }}int A_C(Node *root , char *s) { int len = strlen(s) ; Node *r = root ; int count = 0 ; for(int i = 0 ; i < len ; i++) { if(!isalpha(s[i])) continue ; if(r->next[s[i]-'a'] != NULL) { r = r ->next[s[i]-'a'] ; if(r->is_over && !(islower(s[i+1])) && !(islower(s[i - r->len])) ) count++ ; } else { while(r->next[s[i]-'a'] == NULL && r != root ) r = r ->fail ; if(r ->next[s[i] - 'a'] != NULL) r = r ->next[s[i] - 'a'] ; else r = root ; if(r->is_over && (!(isalpha(s[i+1])) ) && !(islower(s[i - r->len])) ) count++ ; } } return count ;}int main() { int n , m ; int t = 1 ; while(scanf("%d%d",&n,&m) == 2) { Node *root = new_node() ; Node *r = root ; while(n--) { char s[30] ; scanf("%s",&s) ; getchar() ; build_tree(root,s) ; root = r ; } r->fail = NULL ; root = r ; build_fail(r) ; char str[30][100] ; char str1[30][100] ; int count[30] = {0} ; int ma = 0 ; for(int i = 0 ; i < m ; i++) { gets(str[i]) ; strcpy(str1[i],str[i]) ; int len = strlen(str[i]) ; for(int j = 0 ; j < len ; j++) if(isupper(str[i][j])) str[i][j] += 32 ; count[i] = A_C(root,str[i]) ; ma = max(ma,count[i]) ; } cout << "Excuse Set #" << t++ << endl; for(int k = 0 ; k < m ; k++) if(count[k] == ma) cout << str1[k] << endl ; cout << endl ; } return 0 ;}

 

转载于:https://www.cnblogs.com/NYNU-ACM/p/4237457.html

你可能感兴趣的文章
如何给JavaScript文件传递参数
查看>>
开源 高性能 高可用 可扩展
查看>>
JDBC
查看>>
Struts2(十三)国际化-internationalization
查看>>
经典SQL语句基础50题
查看>>
vs2010 无法加载 asp.net mvc2 项目标解决规划
查看>>
去掉^M
查看>>
前台线程和后台线程
查看>>
前端 HTML body标签相关内容 常用标签 表格标签 table
查看>>
【SICP练习】126 练习3.57
查看>>
拟双飞翼布局
查看>>
vue router 根据不同的id切换链接界面不刷新
查看>>
数论:HDU1066-Last non-zero Digit in N!
查看>>
2015-2-10 ecshop
查看>>
REST API disable / enable service auto start by API
查看>>
[转] 17个自适应风格html5网页模板
查看>>
robotframework实战二---Jenkins连用
查看>>
鼠标事件记录
查看>>
Jquery IE 缓存问题
查看>>
【重要】优秀的应试应聘笔记
查看>>