CodeForces 631D Messenger —— (kmp的应用)
这题是一个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的应用)的更多相关文章
- codeforces 631D. Messenger kmp
题目链接 首先想到kmp, 和普通的不一样的是,中间部分严格相等, 头和尾的字符相等但是数量可以不相等. 所以应该把子串的头和尾先去掉,然后对剩下的部分进行kmp. 子串长度为1或2要特别讨论. 不要 ...
- Codeforces 631D Messenger【KMP】
题意: 给定由字符串块(字符及连续出现的个数)组成的字符串t,s,求t串中有多少个s. 分析: KMP 这题唯一需要思考的地方就是如何处理字符串块.第一想到是把他们都展开然后进行KMP,可是展开后实在 ...
- CodeForces 631D Messenger
$KMP$. $n=1$和$n=2$的时候可以单独计算.$n>2$时,可以拿字符和数字分别做一次匹配,然后扫描一遍判断一下就可以计算出答案了. #pragma comment(linker, & ...
- Codeforces Round #344 (Div. 2) D. Messenger kmp
D. Messenger 题目连接: http://www.codeforces.com/contest/631/problem/D Description Each employee of the ...
- 【18.40%】【codeforces 631D】Messenger
time limit per test 2 seconds memory limit per test 512 megabytes input standard input output standa ...
- CF #344 D. Messenger KMP/Z
题目链接:http://codeforces.com/problemset/problem/631/D 给定两个压缩形式的字符串,如a3b5a4k7这样的形式 问A在B中出现次数. 分类讨论,如果A是 ...
- CodeForces 25E Test KMP
Description Sometimes it is hard to prepare tests for programming problems. Now Bob is preparing tes ...
- Codeforces 126B. Password (KMP)
<题目链接> 题目大意:给定一个字符串,从中找出一个前.中.后缀最长公共子串("中"代表着既不是前缀,也不是后缀的部分). 解题分析:本题依然是利用了KMP中next数 ...
- Codeforces 126B(kmp)
要点 头尾的最长相同只要一个kmp即可得,于是处理中间部分 扫一遍记录一下前缀的每个位置是否存在一个中间串跟它相同,见代码 如果当前没有,接着用Next数组去一找即可 #include <cst ...
随机推荐
- java实现4种内部排序
两种插入类排序: 直接插入排序: public static void insertSort(int[] arr, int len){ for(int i=1; i<len; i++){ int ...
- php 处理数字为金钱格式
number_format(需要转换的数字,保留小数个数,小数点符号,每三位的分隔符) echo number_format("1000000")."<br> ...
- mac电脑开机键盘和鼠标失灵
今天早上电脑刚开机发现,触摸板动不了了,过了一会屏幕上就出现蓝牙键盘连接不了的东东,马上意识到键盘也输入不了了.本来还以为得去守候维修了,百度了下解决方法,好在暂时解决了.亲测有效的两个方法(早上晚上 ...
- MySQL自测测试
#建学生信息表student create table student ( sno varchar(20) not null primary key, sname varchar(20) not nu ...
- Django中间件理解
一.中间件 https://www.cnblogs.com/maple-shaw/articles/9333824.html 中间件:是一个类处理django的请求和响应,本质上就是一个类,在类里面定 ...
- 本地套接字-本地socket
本地套接字简单应用场景 一 #服务端--简单 import socket import os a='sock_file' if os.path.exists(a): os.remove(a) s=so ...
- Python学习记录3-函数参数详解
参数详解 参数分类 普通参数 默认参数 关键字参数 收集参数 普通参数 定义时直接定义变量名 调用的时候直接把变量或者值放入指定位置 def 函数名 (参数1, 参数2, ....): 函数体 # 调 ...
- OpenCV入门学习资料汇总
OpenCV学习文档资料 OpenCV学习:1)OpenCV中文网站——http://wiki.opencv.org.cn/index.php/%E9%A6%96%E9%A1%B5 2)python实 ...
- 解决No module named 'sklearn.cross_validation'
sklearn中已经废弃cross_validation,将其中的内容整合到model_selection中 将sklearn.cross_validation 替换为 sklearn.model_s ...
- JavaScript 转换数字为整数的方法
本文将会列举并说明JavaScript 把一个number(或者numerical的对象)转换成一个整数相关方法. 使用parseInt parseInt的语法如下:parseInt(string, ...