双栈+AC自动机

这题其实跟一道KMP算法的题有一些渊源,它就是这道题的简单板。

Clear:

给你两个串A,B,每次在B串中从左到右找串A,并将该子串删除,直到找不到为止,问你能删几次。

样例输入:

abc

abcabcabaabcbccc

样例输出:

5

思路:

开一个栈,每次放入被匹配字符串的一个字符。如果当前栈中字符数量大于等于匹配串的长度,开始匹配,如果有一个单词匹配失败,break掉,继续放字符。

#include<bits/stdc++.h>
using namespace std;
int lc,lb,cnt,flag,ans;
char a[10000001];
string b,c;
int main()
{
cin>>b>>c;
lb=b.size();
lc=c.size();
for(int i=0;i<lc;i++)
{
a[++cnt]=c[i];
if(cnt<b.size())
{
continue;
}
if(a[cnt]!=b[lb-1])
{
continue;
}
flag=0;
for(int i=cnt-lb+1,j=0;i<cnt;i++,j++)//匹配
{
if(a[i]!=b[j])
{
flag=1;//发现目标串,标记。
break;
}
}
if(!flag)
{
ans++;
cnt-=lb;//减长度
}
}
printf("%d\n",ans);//输出
return 0;
}

那么经过这题的思考之后,加强版(就是这题)的思路也应该油然而生了——我们同样用栈做,一个栈命名为s2,用来表示当前节点跑到了AC自动机中的trie树哪里了,另一个栈s3,用来表示最后的字符串留下了原字符串的哪些位上的字符。

如果发现当前这一个栈中的字符的后缀是单词,直接减去单词的长度(所以isword要存的是长度)。

剩下就是输出了。

友情提醒:在洛谷提交的话,末尾最好加个‘\n’。

代码:

#include<bits/stdc++.h>
using namespace std;
int cnt,s2[100010],s3[100010],n,wei,top;//s2是存root,s3是存剩下的。
string s1,s;
queue<int>q;
struct data
{
int b[26],fail,isword;//isword用来存s.size。
}a[1000001];
void build(string t)//建trie树
{
int root=0;
for(int i=0;t[i];i++)
{
int x=t[i]-'a';
if(!a[root].b[x])a[root].b[x]=++cnt;
root=a[root].b[x];
}
a[root].isword=t.size();
}
int main()
{
cin>>s;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s1;
build(s1);
}
for(int i=0;i<26;i++)
{
if(a[0].b[i])
{
q.push(a[0].b[i]);
}
}
while(!q.empty())
{
int k=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(a[k].b[i])
{
a[a[k].b[i]].fail=a[a[k].fail].b[i];
q.push(a[k].b[i]);
}else{
a[k].b[i]=a[a[k].fail].b[i];
}
}
}
int root=0;
//双栈走起
while(wei<s.size())
{
int x=s[wei]-'a';
root=a[root].b[x];
s2[++top]=root;
s3[top]=wei;
if(a[root].isword)
{
top-=a[root].isword;
if(top==0)
{
root=top;
}else{
root=s2[top];
}
}
wei++;
}
for(int i=1;i<=top;i++)
{
cout<<s[s3[i]];
}
putchar('\n');
return 0;
}

QAQAQAQ

洛谷P3121 【[USACO15FEB]审查(黄金)Censoring (Gold)】的更多相关文章

  1. 洛谷 P3121 [USACO15FEB]审查(黄金)Censoring (Gold) 【AC自动机+栈】

    这个和bzoj同名题不一样,有多个匹配串 但是思路是一样的,写个AC自动机,同样是开两个栈,一个存字符,一个存当前点在trie树上的位置,然后如果到了某个匹配串的末尾,则弹栈 #include< ...

  2. 洛谷P3121 审查(黄金)Censoring(Gold) [USACO15FEB] AC自动机

    正解:AC自动机 解题报告: 传送门! 啊我好呆啊其实就挺模板题的,,,只是要一个栈搞一下,,,然后我就不会了,,,是看了题解才get的,,,QAQ 然后写下解法趴QwQ 首先看到多串匹配不难想到AC ...

  3. P4824 [USACO15FEB]Censoring (Silver) 审查(银)&&P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

    P3121 [USACO15FEB]审查(黄金)Censoring (Gold) (银的正解是KMP) AC自动机+栈 多字符串匹配--->AC自动机 删除单词的特性--->栈 所以我们先 ...

  4. P3121 [USACO15FEB]审查(AC自动机)

    题目: P3121 [USACO15FEB]审查(黄金)Censoring (Gold) 解析: 多字符串匹配,首先想到AC自动机 建立一个AC自动机 因为有删除和拼接这种操作,考虑用栈维护 顺着文本 ...

  5. 洛谷 P3121 【[USACO15FEB]审查(黄金)Censoring (Gold)】

    被自己学校OJ的毒瘤测评姬卡到自闭 Hash+栈+优化暴力 其实思路也很简单,就是把单词存进一个结构体,记录其哈希值和长度,然后就可以开始匹配了 但是,理论复杂度很高,为\(O(n*length)\) ...

  6. P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

    吐槽 数据太水了吧,我AC自动机的trie建错了结果只是RE了两个点,还以为数组开小了改了好久 思路 看到多模板串,字符串匹配,且模板串总长度不长,就想到AC自动机 然后用栈维护当前的字符串位置,如果 ...

  7. [洛谷P3121] 审查(黄金) (AC自动机)

    题目描述 FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S.他有一个包含n个单词的列表,列表里的n个单词记为t_1...t_N.他希望从S中删除这些单词. FJ每次在S中找 ...

  8. 洛谷 P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold)

    P3120 [USACO15FEB]牛跳房子(金)Cow Hopscotch (Gold) 就像人类喜欢跳格子游戏一样,FJ的奶牛们发明了一种新的跳格子游戏.虽然这种接近一吨的笨拙的动物玩跳格子游戏几 ...

  9. 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)

    题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...

随机推荐

  1. 品Spring:对@PostConstruct和@PreDestroy注解的处理方法

    在bean的实例化过程中,也会用到一系列的相关注解. 如@PostConstruct和@PreDestroy用来标记初始化和销毁方法. 平常更多的是侧重于应用,很少会有人去了解它背后发生的事情. 今天 ...

  2. 使用.Htaccess文件实现301重定向常用的七种方法

    使用.Htaccess文件实现301重定向常用的七种方法   301重定向对广大站长来说并不陌生,从网站建设到目录优化,避免不了对网站目录进行更改,在这种情况下用户的收藏夹里面和搜索引擎里面可能保存的 ...

  3. mysql库复制

    一.使用navicate复制mysql库 二.使用命令 通过命令:1.创建新数据库CREATE DATABASE `newdb` DEFAULT CHARACTER SET UTF8 COLLATE ...

  4. [Note] GNUstep on Windows

    1.下载与安装 www.gnustep.org/windows/installer.html 下载 GNUstep MSYS System GNUstep Core GNUstep Devel 并安装 ...

  5. IDEA 学习笔记之 Console显示日志大小

    Console显示日志大小: IntelliJ IDEA默认的Output输出缓存区大小只有1024KB,超过大小限制的就会被清除,而且还会显示[too much output to process] ...

  6. 死磕 java线程系列之自己动手写一个线程池(续)

    (手机横屏看源码更方便) 问题 (1)自己动手写的线程池如何支持带返回值的任务呢? (2)如果任务执行的过程中抛出异常了该怎么处理呢? 简介 上一章我们自己动手写了一个线程池,但是它是不支持带返回值的 ...

  7. Tomcat源码分析一:编译Tomcat源码

    Tomcat源码分析一:编译Tomcat源码 1 内容介绍 在之前的<Servlet与Tomcat运行示例>一文中,给大家带来如何在Tomcat中部署Servlet应用的相关步骤,本文将就 ...

  8. asp.net 开源工作流-ccflow关于 “ 是否自动计算未来的处理人”的功能变更

    关键字:流程未来节点处理人  工作流快速开发平台  工作流流设计  业务流程管理   asp.net 开源工作流 业务背景:一个流程在启动起来后,是可以对一些节点计算出来处理人是谁,流程的走向.对于另 ...

  9. Linux 命令个人笔记

    [表示命令]man -f [] 显示一个命令的功能whatis [] 显示一个命令的功能ls -lR | grep '^-' | wc -l 统计一个目录下总共有多少个文件head [-n numbe ...

  10. Python3 os.path() 模块

    os 模块提供了非常丰富的方法用来处理文件和目录.常用的方法如下表所示: 序       号 方法及描述 1 os.access(path, mode):检验权限模式 2 os.chdir(path) ...