您的位置:首页 > 其它

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

2017-07-31 19:01 330 查看
题目链接:点击打开链接

题目大意:

就是说给你两个字符串,让你判断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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: