HDU 6208 AC自动机 或 暴力?
来源:互联网 发布:美国劳工部就业数据 编辑:程序博客网 时间:2024/06/07 02:51
简略题意:问是否存在一个串,其他串都是他的子串。
看了题目之后,可以明确一点,极限数据的情况下,暴力一定过不了。
有可能成为目标串的一定是最长串,所有串建AC自动机,用最长串去匹配。如果匹配到了所有串,那么答案存在。
具体做法就是每访问到一个节点,都看当前节点是否能匹配到某个串,以及这个节点一直在fail树上跳转到根部的这段路径上是否能匹配上某个串。
这题卡自动机做法主要在两点:
1. 卡读入,加了输入挂和不加输入挂相差500ms左右。
2. 每次暴力在fail树跳转需要花费一定时间,并且会重复遍历。
因为我们不需要知道每个字符串在最长串中出现的次数,因此对于遍历过的节点,不需要再重复遍历,加个标记即可。
#include <stdio.h>#include <algorithm>#include <iostream>#include <string.h>#include <queue>#define maxn 27using namespace std;int cnt[100010];int idx(char x) { return x-'a';}struct Trie{ int next[500010][maxn],fail[500010]; vector<int> end[500010]; int root,L; int newnode() { for(int i = 0; i < maxn; i++) next[L][i] = -1; end[L++].clear(); return L-1; } void init() { L = 0; root = newnode(); } void insert(char *buf, int len, int th) { int now = root; for(int i = 0; i < len; i++) { if(next[now][idx(buf[i])] == -1) next[now][idx(buf[i])] = newnode(); now = next[now][idx(buf[i])]; } end[now].push_back(th); } void build() { queue<int>Q; fail[root] = root; for(int i = 0; i < maxn; i++) if(next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; Q.push(next[root][i]); } while( !Q.empty() ) { int now = Q.front(); Q.pop(); for(int i = 0; i < maxn; i++) if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } bool vis[500010]; int query(string buf) { for(int i = 0; i < L; i++) vis[i] = 0; int len = buf.size(); int now = root; int res = 0; for(int i = 0; i < len; i++) { now = next[now][idx(buf[i])]; int temp = now; while( temp != root ) { if(vis[temp]) break; vis[temp] = 1; for(int i = 0; i < end[temp].size(); i++) { int v = end[temp][i]; cnt[v]++; } temp = fail[temp]; } } return res; }};char s[1100000];Trie ac;int n;int t;int main() { cin >> t; while(t--) { cin >> n; for(int i = 1; i <= n; i++) cnt[i] = 0; int maxv = 0, mid; string str; ac.init(); for(int i = 1; i <= n; i++) { scanf("%s", s); int len = strlen(s); if(len > maxv) maxv = len, str = s; ac.insert(s, len, i); } ac.build(); ac.query(str); int sum = 0; for(int i=1; i<=n; i++) { if(cnt[i]) sum++; } for(int i = 0; i <= str.size(); i++) s[i] = str[i]; if(sum != n) puts("No"); else cout<<str<<'\n'; } return 0;}
大家都会写假算法,这游戏越来越难玩了…
#include <bits/stdc++.h>#define maxn 27using namespace std;string s[110000];int main() { cin.tie(0); ios::sync_with_stdio(0); int t, n; cin >> t; while(t--) { cin >> n; int maxv = 0; int id; for(int i = 1; i <= n; i++) { cin >> s[i]; if(s[i].size() > maxv) { maxv = s[i].size(); id = i; } } int cnt = 0; for(int i = 1; i <= n; i++) { if(s[id].find(s[i]) != -1) { cnt++; } } if(cnt ==n) cout<<s[id]<<'\n'; else cout<<"No"<<'\n'; } return 0;}
阅读全文
0 0
- HDU 6208 AC自动机 或 暴力?
- HDU 6208 AC自动机
- hdu 6208 (ac自动机)
- HDU--3407[String-Matching Automata] AC自动机或kmp
- AC自动机 hdu 2222
- HDU 2222(AC 自动机)
- hdu 2222 AC自动机
- hdu 3065(AC自动机)
- HDU 2222 AC自动机
- HDU 2896 AC自动机
- HDU 3065 AC自动机
- HDU 2896 AC自动机
- HDU-3695-ac自动机
- Hdu 2222 [AC自动机]
- hdu 2222 AC自动机 。。
- hdu 3695 ac自动机
- hdu 2896 ac自动机
- hdu 2222 AC自动机
- UVA 796 Critical Links(Tarjan求割边)
- 一个简单的51操作系统
- html、css常考的知识点
- 维护篇 17. 固件升级路径表 ❀ 飞塔 (Fortinet) 防火墙
- 全面理解Java内存模型
- HDU 6208 AC自动机 或 暴力?
- vs2008 MFC工程建立
- 使用ppa源方式安装javaJDK
- thinkPHP3.2.3 中伪造表单的一种示例及解决方法
- 1553: 发红包(2):红包来啦~
- 第三周——项目二—建设“顺序表”算法库
- 题目94-cigarettes
- HDU
- 前端一些记不太住的知识点加深印象