这题是一个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. C#字典转对象

    /// <summary> /// Assign parameters to specified objects /// </summary> /// <typepara ...

  2. git基本操作及实用工具

    //git1.安装客户端git Git-2.9.3-rebase-i-64-bit.exe2.安装完成后打开git bashgit config --global user.name "li ...

  3. 维护solr索引库

    一 2)solrcore    一个solr下可以有多个solrcore,每个solrcore就是一个独立的索引库3)solrconfig.xml    lib:配置solr的扩展包的位置,不指定路径 ...

  4. React 工程的 VS Code 插件及配置

    原味地址:https://juejin.im/post/5b5fce12e51d45162679e032 最近使用 VS Code 来开发 React,本文记录一些使用的 VS Code 插件以及离线 ...

  5. zepto学习(二)之tap事件以及tap事件点透处理

    前言 为什么通过touch可以触发click事件? touch事件的来源 PC网页上的大部分操作都是用鼠标的,即响应的是鼠标事件,包括mousedown.mouseup.mousemove和click ...

  6. [转载]Grid Search

    [转载]Grid Search 初学机器学习,之前的模型都是手动调参的,效果一般.同学和我说他用了一个叫grid search的方法.可以实现自动调参,顿时感觉非常高级.吃饭的时候想调参的话最差不过也 ...

  7. 虚拟机CentOS启动报错-entering emergency mode解决办法

    转载自:https://blog.csdn.net/csdn_yym/article/details/87970960 解决方法只需要在这里的shell键入一条命令: xfs_repair -v -L ...

  8. excel中的更新链接

    表格每次打开都提示是否更新连接 在 [  数据 -->   编辑链接  ]  中也看到了这个连接 学着网上说的查找方式,去查找路径中包含的文字,文件名中包含的名字,都定位不到这个用了链接的单元格 ...

  9. Delphi 重载方法与重定义方法

  10. ASP.config配置

    使用ASP.NET搭建三层时候, 有Model (模型)DAL(数据访问层)    BLL(业务逻辑层)  连接数据库的DBhelper 放在DAL层 假如 你数据库密码改了,你要打开VS 找到DBh ...