zoukankan      html  css  js  c++  java
  • 【KMP】BZOJ3942-[Usaco2015 Feb] Censoring

    【题目大意】

    有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。输出最后的S串。

    【思路】
    三天前写过一次,用的是以前的KMP模板,但是觉得太乱了,数组下标一会儿是下标一会儿是长度,傻傻分不清。参照其他人常见的方法重改了一发,算是比较清晰的KMP了,所有数组下标均直接指代字符串下标。

    维护两个同进同出的栈,s代表当前的U串,a代表在s串种相应位置时的j指针位于模式串中的下标。每次将匹配串的下一位压入s中,用KMP判断匹配。一旦成功匹配到一个,便从栈中弹出即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=1000000+50;
     7 char p[MAXN],t[MAXN],s[MAXN];
     8 int next[MAXN],a[MAXN],len,lenp;
     9 
    10 void getnext()
    11 {
    12     int i=0,j=-1;
    13     next[i]=j;
    14     for (int i=1;i<len;i++)
    15     {
    16         while (j!=-1 && p[i]!=p[j+1]) j=next[j];
    17         if (p[i]==p[j+1]) ++j;
    18         next[i]=j;
    19     }
    20 }
    21 
    22 void solve()
    23 {
    24     int top=0;
    25     for (int i=0;i<len;i++)
    26     {
    27         int j=a[top];
    28         s[++top]=t[i];
    29         while (j!=-1 && p[j+1]!=s[top]) j=next[j];
    30         if (p[j+1]==s[top]) ++j;
    31         a[top]=j;
    32         if (a[top]==lenp-1) top-=lenp;
    33     }
    34     s[top+1]='';
    35     puts(s+1);
    36 }
    37 
    38 int main()
    39 {
    40     scanf("%s%s",t,p);
    41     len=strlen(t),lenp=strlen(p);
    42     getnext();
    43     solve();
    44     return 0;
    45 }
  • 相关阅读:
    CCF NOI1067 最匹配的矩阵
    POJ NOI0105-29 数字反转
    POJ NOI0105-30 含k个3的数
    POJ NOI0105-32 求分数序列和
    POJ NOI0105-33 计算分数加减表达式的值
    POJ NOI0105-34 求阶乘的和
    POJ NOI0105-35 求出e的值
    POJ NOI0105-36 计算多项式的值
    POJ NOI0105-44 第n小的质数
    POJ NOI0105-43 质因数分解
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5710297.html
Copyright © 2011-2022 走看看