这题是一个kmp的应用,思路是有,但是代码实现能力太弱,细节考虑不全,敲了很长时间才AC。。

  题意:字符串用如下的方法表示,例如aaabbbbcc表示为3-a,4-b,2-c。那么问t串在s串中出现了多少次。这题的字符串总长是很长的,如果扩展为原长再kmp内存都不够。那么只能对缩写的状态进行kmp。

  方法如下:

  1.如果缩写长度为1,那么用这个在s串中每个进行比对字符和长度即可。

  2.如果为2,也类似于1。

  3.如果缩写长度大于3,那么由于头和尾匹配的时候不是需要长度也相等,只要长度小于或者等于即可,那么,先把头尾去掉。将身子进行kmp,每个点相同的条件应当是长度和字符都完全相等。其实这里可以写成pair来比较一个点更方便,但是我是用的两个数组,结果写的很挫。。当身子满足以后,再比较头和尾是否满足即可。

  这里有个注意点,在输入的时候如果相邻两个字符时相同的,需要合并,不然会出错。比方说3-a,4-a,用2-a去匹配,在3-a和4-a中间其实也可以放一个2-a,所以不合并的话答案就少了1。

  具体见代码:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <string>
#include <map>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = +; char s[N],t[N],tt[N];
int lena,lenb;
ll numa[N],numb[N];
int nxt[N];
int f,e; void getnxt()
{
nxt[] = ;
int j = ;
for(int i=;i<=lenb-;i++)
{
while(j> && (tt[j+]!=tt[i] || numb[i]!=numb[j+]) ) j=nxt[j];
if(tt[j+] == tt[i] && numb[i]==numb[j+]) j++;
nxt[i]=j;
}
} ll kmp()
{
ll ans = ;
int j = ;
for(int i=;i<lena;i++)
{
while(j> && (tt[j+]!=s[i] || numa[i]!=numb[j+]) ) j=nxt[j];
if(tt[j+]==s[i] && numa[i]==numb[j+]) j++;
if(j == lenb-)
{
if(s[i-(lenb-)]==t[] && s[i+]==t[lenb] && numa[i-(lenb-)]>=f && numa[i+]>=e) ans++;
j = nxt[j];
}
}
return ans;
} int main()
{
int n,m;
lena = lenb = ;
cin>>n>>m;
for(int i=;i<=n;i++)
{
ll x;
char c[];
scanf("%I64d-%s",&x,c);
if(c[]==s[lena]) numa[lena] += x;
else
{
numa[++lena] = x;
s[lena] = c[];
}
} for(int i=;i<=m;i++)
{
ll x;
char c[];
scanf("%I64d-%s",&x,c);
if(c[]==t[lenb]) numb[lenb] += x;
else
{
numb[++lenb] = x;
t[lenb] = c[];
}
} ll ans = ;
if(lenb == )
{
for(int i=;i<=lena;i++)
{
if(s[i]==t[] && numa[i]>=numb[])
{
ans += (ll)numa[i]-numb[]+;
}
}
}
else if(lenb == )
{
for(int i=;i<lena;i++)
{
if(s[i]==t[] && s[i+]==t[] && numa[i]>=numb[] && numa[i+]>=numb[]) ans ++;
}
}
else
{
strcpy(tt+,t+);
tt[lenb] = ;
f = numb[],e = numb[lenb];
for(int i=;i<lenb;i++) numb[i]=numb[i+]; getnxt();
ans = kmp();
}
printf("%I64d\n",ans);
return ;
}

CodeForces 631D Messenger —— (kmp的应用)的更多相关文章

  1. codeforces 631D. Messenger kmp

    题目链接 首先想到kmp, 和普通的不一样的是,中间部分严格相等, 头和尾的字符相等但是数量可以不相等. 所以应该把子串的头和尾先去掉,然后对剩下的部分进行kmp. 子串长度为1或2要特别讨论. 不要 ...

  2. Codeforces 631D Messenger【KMP】

    题意: 给定由字符串块(字符及连续出现的个数)组成的字符串t,s,求t串中有多少个s. 分析: KMP 这题唯一需要思考的地方就是如何处理字符串块.第一想到是把他们都展开然后进行KMP,可是展开后实在 ...

  3. CodeForces 631D Messenger

    $KMP$. $n=1$和$n=2$的时候可以单独计算.$n>2$时,可以拿字符和数字分别做一次匹配,然后扫描一遍判断一下就可以计算出答案了. #pragma comment(linker, & ...

  4. Codeforces Round #344 (Div. 2) D. Messenger kmp

    D. Messenger 题目连接: http://www.codeforces.com/contest/631/problem/D Description Each employee of the ...

  5. 【18.40%】【codeforces 631D】Messenger

    time limit per test 2 seconds memory limit per test 512 megabytes input standard input output standa ...

  6. CF #344 D. Messenger KMP/Z

    题目链接:http://codeforces.com/problemset/problem/631/D 给定两个压缩形式的字符串,如a3b5a4k7这样的形式 问A在B中出现次数. 分类讨论,如果A是 ...

  7. CodeForces 25E Test KMP

    Description Sometimes it is hard to prepare tests for programming problems. Now Bob is preparing tes ...

  8. Codeforces 126B. Password (KMP)

    <题目链接> 题目大意:给定一个字符串,从中找出一个前.中.后缀最长公共子串("中"代表着既不是前缀,也不是后缀的部分). 解题分析:本题依然是利用了KMP中next数 ...

  9. Codeforces 126B(kmp)

    要点 头尾的最长相同只要一个kmp即可得,于是处理中间部分 扫一遍记录一下前缀的每个位置是否存在一个中间串跟它相同,见代码 如果当前没有,接着用Next数组去一找即可 #include <cst ...

随机推荐

  1. VNote: 一个舒适的Markdown笔记软件

    Update: 支持macOSYunpan Update 2: 写在VNote半周岁 QQ群(487756074) Markdown标记语言一直是许多程序员的最爱.目前,有许多优秀的Markdown编 ...

  2. django管理系统代码优化-分组(二)

    django管理系统代码优化-分组(二) 后续进行代码更新,优化 一优化的内容 优化前代码:https://www.cnblogs.com/pythonywy/p/11345626.html 路由进行 ...

  3. Java Web-EL表达式 in JSP

    Java Web-EL表达式 in JSP 概念 EL(Expression Language)是一种表达式语言,可以替换和简化JSP页面上JAVA代码的书写 语法 ${<在这里写表达式> ...

  4. LLVM新建全局变量

    在LLVM中,有原生的AST Clone,却没有一个比较好的Stmt copy功能,基于Scout在LLVM上进行的修改,我们实现了自己的Stmt Clone功能. 要进行Stmt Clone,肯定需 ...

  5. mock.js学习之路一(Vue中使用)

    1.安装mockjs 2.配置mockjs在开发环境中启用,生产环境中禁用 3.创建mock文件夹,以及mock数据文件 4.在main.js中引入与否 5.页面获取数据 testMock(){ th ...

  6. 2-1 bash基本特性

    bash基本特性 bash基本介绍 bash是shell的一种,shell是计算机与用户交互的主要接口,狭义上的shell指的是CLI(command line interface命令行接口),用户输 ...

  7. SQL使用 dateadd添加使天数加x

    ,Receivedate)), ) --第一个参数 表示增加什么(day ) --第二个参数表示增加多少( int ) --第三个参数表示那个字段  (Receivedate 字段属性) conver ...

  8. Shell 语法报错记录

    sh: missing ] if 条件语句 “或”多个条件并行时 执行then命令 变量a等于aa且变量b等于bb 或者 变量c等于cc且变量d等于dd 这样的条件成立的话,输出success if ...

  9. Almost Acyclic Graph CodeForces - 915D (思维+拓扑排序判环)

    Almost Acyclic Graph CodeForces - 915D time limit per test 1 second memory limit per test 256 megaby ...

  10. shell脚本基础编写

    shell脚本的格式 名称:Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将 .sh 后缀加上,以表示是一个脚本文件. shell 脚本中一般会出现三种不同的元素: 第一行的脚 ...