CodeForces 471D(2020.3.8训练G题)

题目:
Polar bears Menshykov and Uslada from the zoo of St. Petersburg and elephant Horace from the zoo of Kiev got hold of lots of wooden cubes somewhere. They started making cube towers by placing the cubes one on top of the other. They defined multiple towers standing in a line as a wall. A wall can consist of towers of different heights.

Horace was the first to finish making his wall. He called his wall an elephant. The wall consists of w towers. The bears also finished making their wall but they didn’t give it a name. Their wall consists of n towers. Horace looked at the bears’ tower and wondered: in how many parts of the wall can he “see an elephant”? He can “see an elephant” on a segment of w contiguous towers if the heights of the towers on the segment match as a sequence the heights of the towers in Horace’s wall. In order to see as many elephants as possible, Horace can raise and lower his wall. He even can lower the wall below the ground level (see the pictures to the samples for clarification).

Your task is to count the number of segments where Horace can “see an elephant”.

Input
The first line contains two integers n and w (1 ≤ n, w ≤ 2·105) — the number of towers in the bears’ and the elephant’s walls correspondingly. The second line contains n integers ai (1 ≤ ai ≤ 109) — the heights of the towers in the bears’ wall. The third line contains w integers bi (1 ≤ bi ≤ 109) — the heights of the towers in the elephant’s wall.

Output
Print the number of segments in the bears’ wall where Horace can “see an elephant”.

题意:有两个数字数组,给了两个数组的长度n和m,也提供了两个数组,求数组2可与数组1匹配次数,但这匹配和传统匹配不太一样,比如比较1 2 3 4 5和2 3 4 5 6两个片段时,2 3 4 5 6可同时对每个数字进行自减或是自加操作,于是两个片段成功匹配,思考题意易得,满足这样匹配的两个片段一定是下一个数字相对于前一个数字的增减情况相同,所以对两个数组进行后一个数减前一个数成为一个新的数组(当然长度为x的数组变新后长度为x-1),然后用kmp算法,可得答案

但也要考虑1的特判,一直没想到= =于是一直wa(n和m可能为1的情况)

如下给出ac代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>

using namespace std;
const int maxl = 200005;
#define ll long long 
int s1[200005],s2[200005];
int s3[200005],s4[200005];
ll p[200005];

int main()
{

	ll ans = 0;
	ll n, m;
	cin >> n >> m;

	for (ll i = 1; i <= n; i++)
	{
		cin>>s2[i];
	}

	for (ll i = 1; i <= m; i++)
	{
		cin>>s1[i];
	}

	if (m == 1)
		ans += n;//特判不要忘*****

	else if (n >= m)
	{
		ll cnt = 1;
		ll num1, num2;

		for (ll i = 2; i <= m; i++)
		{
			s3[cnt]=s1[i] - s1[i-1];//后数减前数成为新的数组
			cnt++;
		}

		num1 = cnt - 1;//新数组长度减一
		cnt = 1;

		for (ll i = 2; i <= n; i++)
		{
			s4[cnt] = s2[i] - s2[i-1];//同上
			cnt++;
		}

		num2 = cnt-1;	   
		p[1] = 0;
		
		for (ll i = 2, j = 0; i <= num1; i++)//求next数组(p数组)
		{	
			while (s3[j+1] != s3[i] && j != 0) 
				j = p[j];
			if (s3[j+1] == s3[i]) 
				j++;
			p[i] = j;
		}
	
		for (ll i = 1, j = 0; i <= num2; i++)//kmp算法求最大匹配数
		{
			if (j+1 > num1)
				j = p[j];
			while (s3[j+1] != s4[i] && j != 0) 
				j = p[j];
			if (s3[j+1] == s4[i]) 
				j++;
			if (j == num1) 
				ans++;
		}

	}
	    
	printf("%d\n",ans);
	   
}
发布了16 篇原创文章 · 获赞 21 · 访问量 1333

猜你喜欢

转载自blog.csdn.net/rainbowower/article/details/104776011