BZOJ 1195: [HNOI2006]最短母串

1195: [HNOI2006]最短母串

Time Limit: 10 Sec  Memory Limit: 32 MB
Submit: 1346  Solved: 450
[Submit][Status][Discuss]

Description

给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串。

Input

第一行是一个正整数n(n<=12),表示给定的字符串的个数。以下的n行,每行有一个全由大写字母组成的字符串。每个字符串的长度不超过50.

Output

只有一行,为找到的最短的字符串T。在保证最短的前提下,如果有多个字符串都满足要求,那么必须输出按字典序排列的第一个。

Sample Input

2
ABCD
BCDABC

Sample Output

ABCDABC

HINT

Source

[Submit][Status][Discuss]

不明白网上为啥题解都写的那么复杂,还说可以hack别人,好怕怕哦……

 1 #include<cstdio>
 2 #define N 605
 3 #define M (1<<12)
 4 #define chr char
 5 #define sht short
 6 chr s[55];
 7 int n,tt=1;
 8 sht fl[N];
 9 int ed[N];
10 sht ch[N][26];
11 int q[N*M],l,r;
12 sht f[N][M];
13 int p[N][M];
14 sht c[N][M];
15 sht stk[N],tp;
16 main(){
17     scanf("%d",&n);
18     for(int i=0;i<n;++i){
19         scanf("%s",s); int t=1;
20         for (char *c=s;*c;++c){
21             if(!ch[t][*c-‘A‘])
22                 ch[t][*c-‘A‘]=++tt;
23             t=ch[t][*c-‘A‘];
24         }
25         ed[t]|=1<<i;
26     }
27     fl[1]=1;
28     for(int i=0;i<26;++i)
29         if(ch[1][i])
30             fl[q[r++]=ch[1][i]]=1;
31         else
32             ch[1][i]=1;
33     while(l!=r){
34         int t=q[l++];
35         for(int i=0;i<26;++i)
36             if(ch[t][i])
37                 fl[q[r++]=ch[t][i]]=ch[fl[t]][i],
38                 ed[ch[t][i]]|=ed[ch[fl[t]][i]];
39             else
40                 ch[t][i]=ch[fl[t]][i];
41     }
42     l=r=0;q[r++]=1<<n;f[1][0]=1;
43     while(l!=r){
44         int id=q[l]>>n,bt=q[l]&((1<<n)-1);++l;
45         for(int i=0;i<26;++i){
46             int v=ch[id][i],b=bt|ed[v];
47             if(f[v][b])continue;
48             f[v][b]=1;q[r++]=v<<n|b;
49             p[v][b]=id<<n|bt;
50             c[v][b]=i;
51             if(b==(1<<n)-1)goto out;
52         }
53     }
54 out:int id=q[r-1]>>n,bt=(1<<n)-1;
55     while(id!=1){
56         stk[++tp]=c[id][bt];
57         int pp=p[id][bt];
58         id=pp>>n;
59         bt=pp&((1<<n)-1);
60     }
61     while(tp)putchar(‘A‘+stk[tp--]);puts("");
62 }

@Author: YouSiki

时间: 2024-08-06 14:40:06

BZOJ 1195: [HNOI2006]最短母串的相关文章

bzoj 1195: [HNOI2006]最短母串 爆搜

1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 894  Solved: 288[Submit][Status][Discuss] Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12),表示给定的字符串的个数.以下的n行,每行有一个全由大写字母组成的字符串.每个字符串的

2782: [HNOI2006]最短母串

2782: [HNOI2006]最短母串 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3  Solved: 2[Submit][Status][Web Board] Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12),表示给定的字符串的个数.以下的n行,每行有一个全由大写字母组成的字符串.每个字符串的长度

Bzoj1195 [HNOI2006]最短母串 [AC自动机]

Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12),表示给定的字符串的个数.以下的n行,每行有一个全由大写字母组成的字符串.每个字符串的长度不超过50. Output 只有一行,为找到的最短的字符串T.在保证最短的前提下,如果

[BZOJ1195]最短母串

1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MB Description 给定n个字符串(S1,S2,?,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,?,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12),表示给定的字符串的个数.以下的n行,每行有一个全由大写字母组成的字符串.每个字符串的长度不超过50. Output 只有一行,为找到的最短的字符串T.在保证最短的前提下,如果有多个字

最短母串

Ac_automaton的与状压的结合. 看题解说是Ac_automaton上的dp,但是实际上没有十分明显的转移过程,仅仅使用状压的方式记录某个串是否被选择过了(当然有建完Ac_automation然后跑纯状压dp的解法). 首先建立Ac_automaton(Trie图),额外维护一个sta数组,该数组为一个二进制表示数组,‘1’表示该串出现过,‘0’表示该串为出现过.这个信息需要在insert与generate(build)过程中统计,然而有趣的是,网上的大部分题解仅有由fail更新当前节点

【题解】最短母串

题目大意 ??有\(n\)个字符串\(s_1,s_2,\dots,s_n\),求一个最短的字符串\(S\),使这\(n\)个字符串都是\(S\)的子串. ? 题解 ??我们先对这\(n\)个字符串建AC自动机,这里我们对于Trie上的结点\(i\),定义一个状态\(state_i\),表示第\(i\)个结点对应的字符串,包含的题目中给出的哪些字符串. ??我们可以从Trie上的根节点,按照字典序BFS,我们用\(f\)表示当前经过的所有结点的包含的所有字符串,显然,当\(f\)包含所有字符串时,

python 字符串函数find功能拓展——查找母串内所有子串的位置

前言 我们知道,字符串内置了很多功能的处理函数,其中,find.index函数都可以接受一个参数意义是作为目标子串,而返回母串中从左到右遍历时子串第一次出现的索引值(每一次调用都是从头开始,没有记忆),如果查询不到返回-1. 如下面的例子: 如果,子串不在母串中出现,则find函数返回-1,而index方法返回ValueError错误,这也是两者的区别,接上例: 深入 rindex rfind函数:功能类似,把母串从右向左遍历,找到子串第一次出现的位置,也没有记忆性. 后续 我编写了一个函数,实

字符串(马拉车算法,后缀数组,稀疏表):BZOJ 3676 [Apio2014]回文串

Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行,为一个只包含小写字母(a -z)的非空字符串s. Output 输出一个整数,为逝查回文子串的最大出现值. Sample Input [样例输入l] abacaba [样例输入2] www Sample Output [样例输出l] 7 [样例输出2] 4 HINT 一个串是回文的,当且仅当它从左

BZOJ 1191: [HNOI2006]超级英雄Hero(二分图匹配)

云神说他二分图匹配从来都是用网络流水过去的...我要发扬他的精神.. 这道题明显是二分图匹配.网络流的话可以二分答案+最大流.虽然跑得很慢.... ---------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostrea