Link

一句话题意:

给两堵墙。问 \(a\) 墙中与 \(b\) 墙顶部形状相同的区间有多少个.

这生草翻译不想多说了。

我们先来转化一下问题。对于一堵墙他的向下延伸的高度,我们是不用管的。

我们只需要考虑的是上边延伸的高度,那我们可以求出相邻的两个块之间的高度差。

我们要求的是 \(a\) 中连续的一段与 \(b\) 完全相同的数量。

其实就是 \(kmp\) 匹配啦。

注意特判一下 \(m=1\) 的情况。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define int long long
const int inf = 2147483647;
const int N = 3e5+10;
int n,m,ans,h[N],t[N],a[N],b[N],net[N];
inline int read()
{
int s = 0,w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
return s * w;
}
signed main()
{
n = read(); m = read();
if(m == 1) {printf("%d\n",n); return 0;}
for(int i = 1; i <= n; i++) h[i] = read();
for(int i = 1; i <= m; i++) t[i] = read();
for(int i = 1; i <= n-1; i++) a[i] = h[i] - h[i+1];//求一下相邻的两个的高度差
for(int i = 1; i <= m-1; i++) b[i] = t[i] - t[i+1];
b[m] = -inf;
int j = 0;
for(int i = 2; i < m; i++)//kmp
{
while(j && b[i] != b[j+1]) j = net[j];
if(b[i] == b[j+1]) j++;
net[i] = j;
}
j = 0;
for(int i = 1; i < n; i++)
{
while(j && a[i] != b[j+1]) j = net[j];
if(a[i] == b[j+1]) j++;
if(j == m-1) ans++;
}
printf("%d\n",ans);
return 0;
}

最新文章

  1. 【新手总结】在.Net项目中使用Redis作为缓存服务
  2. Linux常用命令:sed
  3. 一些常用的String方法 C#
  4. C#小程序飞行棋关卡操作
  5. JS 获取浏览器和屏幕宽高信息
  6. Excel列名 字母和数字的转换
  7. Entity Framework 5中应用表值函数进行Linq查询
  8. JAVA 回调机制(callback)
  9. 【OpenCV &amp; CUDA】OpenCV和Cuda结合编程
  10. 使用Vue编写点击数字小游戏
  11. MTK 平台上如何给 camera 添加一种 preview size
  12. DDR(一)
  13. 152. Maximum Product Subarray
  14. Sitemesh 3 的使用及配置
  15. 【Android - 框架】之ORMLite的使用
  16. PHP定义数组常量
  17. NSIS:设置文件属性的方法
  18. 利用微信公众平台实现自动回复消息—java版
  19. 微信js-sdk分享详解及demo实例
  20. SQL Server统计数据库中表个数、视图个数、存储过程个数

热门文章

  1. RVO+CA
  2. 深入了解Kafka【四】消费者的Offset管理
  3. Webpack 入门指迷
  4. 图像通道、RGB与色彩体系
  5. 转载:人家编写的程序:「雀神 AI」Suphx
  6. 20190923-11Linux crond 系统定时任务 000 019
  7. MySQL通过实体经纬度字段插入数据库point类型的经纬度字段
  8. shell 设置进程数运行
  9. 购书网站前端实现(HTML+CSS+JavaScript)
  10. Scrapy框架的架构原理解析