Codeforces Round #269 (Div. 2) D

D. MUH and Cube Walls


        题意:给两个数列a1~an,b1~bw,问在b数列中每两个相邻的数的增减情况是否和a数列中的某些段的增减情况相吻合。求共有几处吻合。

        思路:KMP算法。把字符的匹配换成了增减量的匹配,预处理相邻数的差,注意第一个数没有上一个数,所以不用匹配第一个数。还有就是b的长度为1的情况需要考虑。


#include <iostream>      
#include <stdio.h>      
#include <cmath>      
#include <algorithm>      
#include <iomanip>      
#include <cstdlib>      
#include <string>       
#include <vector>      
#include <queue>      
#include <stack>      
#include <map>    
#include <set>    
#include <string.h>
#include <ctype.h>      
  
using namespace std;    

#define ll long long

int a[200010];
int aa[200010];
int b[200010];
int bb[200010];
int next[200010];


int main(){
	int n ,w;
	while(cin>>n>>w){
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		aa[1]=0;
		for(int i=2;i<=n;i++){
			aa[i-1]=a[i]-a[i-1];
		}
		
		for(int i=1;i<=w;i++){
			scanf("%d",&b[i]);
		}
		bb[1]=0;
		for(int i=2;i<=w;i++){
			bb[i-1]=b[i]-b[i-1];
		}
		
		next[1]=0;
		int j=0;
		for(int i=2;i<w;i++){
			
            while(j&&bb[j+1]!=bb[i]){  
                j=next[j]; 
            }
            if(bb[i]==bb[j+1])j++; 
			next[i]=j; 
        }  
		
		int ans=0;
		j=0;
		for(int i=1;i<n;i++){
            while(j&&bb[j+1]!=aa[i]){
                j=next[j];  
            }  
            if(aa[i]==bb[j+1])
                j++;
            if(j==w-1){
            	ans++;
            	j=next[j];
            }
        }
		
		if(w==1){
			cout<<n<<endl;
		}else{
			cout<<ans<<endl;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值