hdu-4749:Parade Show(kmp模板题)

本文介绍了一种特殊的字符串匹配问题,使用KMP算法解决两个字符串中相邻元素大小关系匹配的问题,并提供了一段C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开链接


题目大意:

就是说给你两个字符串,让你判断a串中有多少个不相交并且和b串匹配的子串。但是匹配的方式不是相等,而是指两个串中同样位置相邻的两个数大小关系相同。即你最后得到的和b串匹配的a的子串,不一定和b一样,但是相邻两个数大小关系一定一样。例如 2 4 2 2,4 8 4 4,1 5 2 2等都属于匹配的串。

解题思路:

两个串的匹配问题,毫无疑问是kmp算法,怎奈比赛中这道题看都没看懂,不,是压根看都没看,唉,

kmp算法当然不能直接套,怎么办呢,改模板啊。不就是判断匹配本来是两个字符相等现在是相邻两个大小关系相等嘛,模板改一下,bug调 一下,例如b串只有一个元素的情况( 反正我这算法解决不了,逃~),遂A、

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
#include <functional>
#define next ne
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
int n,m,k,ans;
int a[100005];
int b[100005];
int next[100005];
bool check(int x1,int x2,int y1,int y2)     //将kmp中原先判断相等的条件更换为check
{
    if(x1<x2&&y1<y2)
        return 1;
    else if(x1>x2&&y1>y2)
        return 1;
    else if(x1==x2&&y1==y2)
        return 1;
    else
        return 0;
}
void vs(int a[])
{
    int l=m;
    int i=0;
    int j=-1;
    next[0]=-1;
    while(i<l)
    {
        if(j==-1||a[i]==a[j])
        {
            i++;
            j++;
            next[i]=j;
        }
        else
            j=next[j];
    }
}
void kmp(int s[],int t[])       //kmp模板直接套
{
    int ls=m;
    int lt=n;
    int j=0;
    int i=0;
    vs(s);
    while(i<lt&&j<ls)
    {
        if(j==-1||(check(s[j],s[j+1],t[i],t[i+1])))     //原先的相等改一下
        {
            i++;
            j++;
            if(j==ls-1&&i<lt)       //判断成功以后从i+1继续判断
            {
                ans++;
                i=i+1;
                j=0;
            }
        }
        else
            j=next[j];
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<m;i++)
            scanf("%d",&b[i]);
        if(m==1)        //特判m=1的情况
            printf("%d\n",n);
        else
        {
            ans=0;
            kmp(b,a);
            printf("%d\n",ans);
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值