【题目描述】

)。他想剪出其中一些并且粘帖成一个很长的字母串。

J太懒了,他想用最少的次数裁剪信件。他有一把举世无双的剪刀,他可以从一封信中只剪一刀剪出连续一段。同样,剪一刀可以得到整个完整的字符串。

他想知道他最少需要剪多少刀从而获得这封个字母的长信?

保证这总是可能的。 

考虑下面38个字母的信:
THEQUICKBROWNFOXDO 

GJUMPSOVERTHELAZYDOG 

以及FJ想要获得的9个字母的信: 

FOXDOG DOG 

以上是为了读入方便,实际上这两封信就是: 

THEQUICKBROWNFOXDOGJUMPSOVERTHELAZYDOG 

FOXDOGDOG 

由于FOXDOG已经存在了,J可以选择其中任何一个DOG剪下来。

因此,他一共要剪2刀。

【输入格式】

第1行: 两个空格分隔的整数: M  

第2..?行: 一些行包含J原来拥有的信,每行不会超过80个字母。  

第?...?行: 一些行包含J想要写的信,每行不会超过80个字母。

【输出格式】

第1行: J获得他想要写的信所需要切的最少次数。

【样例输入】

38 9

THEQUICKBROWNFOXDO

GJUMPSOVERTHELAZYDOG

FOXDOG

DOG

【样例输出】

2

【来源】

J.Kuipers, 2002

  注意SAM要开两倍空间,不然死得惨……
  这里每次贪心地匹配最长的一段,失配后直接回rt即可,记得最后答案要加1,因为计数是失配一次才加一次。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int maxn=100010;
 6 int read(){
 7     char c=getchar();
 8     while(c<'A'||c>'Z')
 9         c=getchar();
10     return c-'A';    
11 }
12 int fa[maxn],len[maxn];
13 int lst,cnt,ch[maxn][26];
14 struct SAM{
15     SAM(){cnt=lst=1;}
16     void Insert(int c){
17         int p=lst,np=lst=++cnt;len[np]=len[p]+1;
18         while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
19         if(!p)fa[np]=1;
20         else{
21             int q=ch[p][c],nq;
22             if(len[q]==len[p]+1)
23                 fa[np]=q;
24             else{
25                 nq=++cnt;len[nq]=len[p]+1;
26                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
27                 fa[nq]=fa[q];fa[q]=fa[np]=nq;
28                 while(ch[p][c]==q)ch[p][c]=nq,p=fa[p];
29             }    
30         }
31     }
32 }sam;
33 int n,m;
34 int main(){
35     freopen("thre_letter.in","r",stdin);
36     freopen("thre_letter.out","w",stdout);
37     scanf("%d%d",&n,&m);
38     for(int i=1;i<=n;i++)
39         sam.Insert(read());
40     int p=1,ans=0;
41     for(int i=1;i<=m;i++){
42         int c=read();
43         if(!ch[p][c])
44             {ans+=1;p=1;}
45         p=ch[p][c];
46     }    
47     printf("%d\n",ans+1);
48     return 0;
49 }

 

相关文章:

  • 2022-02-22
  • 2022-01-23
  • 2022-12-23
  • 2021-12-25
  • 2022-02-15
  • 2022-03-04
  • 2022-12-23
  • 2021-11-07
猜你喜欢
  • 2022-01-24
  • 2021-11-02
  • 2021-11-08
  • 2021-10-06
  • 2021-05-23
  • 2021-07-09
  • 2021-06-13
相关资源
相似解决方案