hdu 6208 (ac自动机)
来源:互联网 发布:java源码如何变成软件 编辑:程序博客网 时间:2024/05/24 06:16
Here you have a set of strings. A dominator is a string of the set dominating all strings else. The string SS is dominated by TT if SS is a substring of TT.
Input
The input contains several test cases and the first line provides the total number of cases.
For each test case, the first line contains an integer NN indicating the size of the set.
Each of the following NN lines describes a string of the set in lowercase.
The total length of strings in each case has the limit of 100000100000.
The limit is 30MB for the input file.
Output
For each test case, output a dominator if exist, or No if not.
Sample Input
3
10
you
better
worse
richer
poorer
sickness
health
death
faithfulness
youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness
5
abc
cde
abcde
abcde
bcde
3
aaaaa
aaaab
aaaac
Sample Output
youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness
abcde
No
题意:问有没有一个串包含其他所有串
找最长的串匹配就好
我的板子得加优化,优化就是 用strcmp判和最长的相等的
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; const int LetterSize = 26; const int TrieSize = 10000*50+5; int tot, root, fail[TrieSize], val[TrieSize], Next[TrieSize][LetterSize]; int mark[TrieSize];int newnode(void) { memset(Next[tot], -1, sizeof(Next[tot])); val[tot] = 0; mark[tot] = 0; return tot++; } void init(void) { tot = 0; root = newnode(); } int getidx(char x) { return x-'a'; } void insert(char *ss) { int len = strlen(ss); int now = root; for(int i = 0; i < len; i++) { int idx = getidx(ss[i]); if(Next[now][idx] == -1) Next[now][idx] = newnode(); now = Next[now][idx]; } val[now]++; } void build() { queue<int> Q; fail[root] = root; for(int i = 0; i < LetterSize; 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 < LetterSize; 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]); } } } int match(char *ss) { int len = strlen(ss), now = root, res = 0; for(int i = 0; i < len; i++) { int idx = getidx(ss[i]); int tmp = now = Next[now][idx]; while(tmp&&!mark[tmp]) { res += val[tmp]; val[tmp] = 0; mark[tmp]=1; tmp = fail[tmp]; } } return res; } const int maxn = 1e6+5; char s[maxn+maxn+100]; int st[maxn];int le[maxn];int main() { int t, n; scanf("%d",&t); while(t--) { scanf("%d", &n); int l=0; int lenn=0,MAX=0,flag=0; for(int i = 1; i <= n; i++) { scanf(" %s", s+l); int len=strlen(s+l); le[i]=len; st[i]=l; if(len>lenn) { lenn=len; MAX=i; } l=l+len+1; } int ab=0; init(); for(int i=1;i<=n;i++) { if(le[i]==lenn) { if(strcmp(s+st[i],s+st[MAX])!=0) { flag=1; break; } } else insert(s+st[i]),ab++; } if(flag) { printf("No\n"); continue; } build(); int tt=match(s+st[MAX]); if(tt==ab) printf("%s\n",s+st[MAX] ); else printf("No\n"); } return 0; }
另外 比较好的板子是能直接过的,这个相比于上面的优化在于last数组,保证转移到的位置尽可能是有值的位置,小优化
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=100010;const int maxm=100010;const int SIGMA_SIZE=26;int n;char t[maxn],s[2*maxn+100];int st[maxn];struct AC{ int ch[maxm][26]; int val[maxm]; int fail[maxm],last[maxm]; int sz; void clear(){memset(ch[0],0,sizeof(ch[0]));sz=1;} int idx(char x){return x-'a';} void insert(char *s) { int u=0; int n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]++; } void getfail() { queue<int> q; fail[0]=0; int u=0; for(int i=0;i<SIGMA_SIZE;i++) { u=ch[0][i]; if(u){q.push(u);fail[u]=0;last[u]=0;} } while(!q.empty()) { int r=q.front();q.pop(); for(int i=0;i<SIGMA_SIZE;i++) { u=ch[r][i]; if(!u){ch[r][i]=ch[fail[r]][i];continue;} q.push(u); int v=fail[r]; while(v&&!ch[v][i])v=fail[v]; fail[u]=ch[v][i]; last[u]=val[fail[u]]?fail[u]:last[fail[u]]; } } } int find(char *s) { int u=0,cnt=0; for(int i=0;s[i];i++) { int c=idx(s[i]); u=ch[u][c]; int temp=0;//必须赋初值为0,表示如果下面两个判断都不成立的时候while可以正常执行 if(val[u]) temp=u; else if(last[u]) temp=last[u]; while(temp) { cnt+=val[temp]; val[temp]=0; temp=last[temp]; } } return cnt; }}tree;int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d",&n); int maxlen=0; tree.clear(); int lenn=0,l=0; int MAX=0; for(int i=1;i<=n;i++) { scanf("%s",s+l); int len=strlen(s+l); st[i]=l; if(len>lenn) { lenn=len; MAX=i; } l=l+len+1; } for(int i=1;i<=n;i++) { if(i==MAX) continue; tree.insert(s+st[i]); } tree.getfail(); int ans=tree.find(s+st[MAX]); if(ans==n-1) { printf("%s\n",s+st[MAX]); } else { printf("No\n"); } } return 0;}
标程是假算法 strstr
#include <bits/stdc++.h>using namespace std;char s[200010];int st[100010];int main(){ int T; scanf("%d",&T); while(T--) { int l=0,lenn=0,MAX=0; int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s+l); st[i]=l; int len=strlen(s+l); if(len>lenn) { lenn=len; MAX=i; } l=l+len+1; } int flag=0; for(int i=1;i<=n;i++) { if(i==MAX) continue; if(strstr(s+st[MAX],s+st[i])==NULL) { flag=1; break; } } if(flag) printf("No\n"); else printf("%s\n",s+st[MAX] ); }}
- hdu 6208 (ac自动机)
- HDU 6208 AC自动机
- hdu 3065(ac自动机)
- HDU 2222 (AC自动机)
- Hdu 2222(AC 自动机)
- HDU 3065 (AC自动机)
- hdu 2896 (AC自动机)
- HDU 2222 (AC自动机)
- AC自动机(hdu 2896 hdu 3065)
- HDU 6208 The Dominator of Strings (AC自动机)
- HDU 6208 AC自动机 或 暴力?
- HDU 2222 keyword search(AC自动机)
- hdu 2222(AC自动机入门题)
- hdu 2222(ac自动机入门题)
- hdu 2896(ac自动机简单应用)
- hdU 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- HDU 2896 病毒侵袭(AC自动机)
- Spring MVC框架的个人理解
- php扩展之PDO
- Python Opencv旋转图片90度
- 第三届“工业4.0与中国制造2025全球年会”(IMGAC)j即将于11月盛大绽放!
- Python 中dict 字典方法小结
- hdu 6208 (ac自动机)
- 写代码小技巧
- 170919_Spring英文文档阅读(十一)_2.3 Usage scenarios(三)
- Xcode8快捷键功能
- ubuntu安装svn及配置使用
- java实训第四节单例模式
- Linux基本使用
- HDU2041 超级楼梯 动态规划入门-递推
- 素材资源网站