这题是一个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. 利用Mathpix Snipping Tool轻松在markdown/LaTeX中输入电子书和论文的数学公式

    最近写图形学博客写累了,公式太多了,一个个输入实在太累,所以从数学建模队友那里吃了一个安利. 官网下载 下载安装后,直接新建一个截图,就可以转成LaTeX数学公式了.效果如下: 爽的一批啊!!! 另外 ...

  2. 常用javascript内置对象——String对象

    创建 String 对象的语法: 1:new String(s); :2:String(s); :3:直接赋值 String中属性 String中方法 <script> window.on ...

  3. java lesson10homework

    1.    输入三个整数x, y, z,请把这三个数由小到大输出. 2.  package Homework10; 3.  //:类方法 4.  public class Sort { 5.  voi ...

  4. ADO.NET连接数据库增删查改创建公用类

    顺序如下:再web.config中添加数据库的用户名和密码 创建公用类. //添加进web.config中的账号和密码 /*<connectionStrings> <add name ...

  5. VBA学习资料分享-1

    近年来,人工智能的概念深入人心,许多企业也正逐步或已推行办公自动化,寻求人力时间成本的降低,从而提升效益.对企业来说,要完全使用人工智能将工作流程自动化恐怕是没那么容易的,可以的话成本也不低,所以使用 ...

  6. Django rest-framework框架-CBV原理

    jdango中间件:class Test(View): def dispatch(self, request, *args, **kwargs): #第一种方法 func = getattr(self ...

  7. adb实操

    一.命令 adb connect IP:5555 adb disconnect IP:5555 adb remount adb install 安装包的绝对路径 二.获取logcat信息 1.制作文件 ...

  8. vscode 踩坑汇总

    gopls 提示 update 将 "go.useLanguageServer": true 改为 "go.useLanguageServer": false

  9. linux基础1_文件类型、拓展名、目录配置

    命令ls -l,显示的第一个属性代表了这个档案的档案类型 [d]:目录 [-]:普通文件 [l]:连接文件 [b]:存储数据以供系统访问的接口设备 [c]:串行接口的端口设备,例如键盘.鼠标 [s]: ...

  10. 【Java 关键字this 的使用】还阔以调用重载的构造方法

    笔记: /** this 关键字的使用除了调用方法和变量外, * 还可以用来显示 调用当前类的重载的指定的构造方法! * 同时也应该必须放到该方法内部的首行! */ 测试: import java.l ...