题目链接:http://codeforces.com/group/1EzrFFyOc0/contest/471/problem/D
题目思路:这题主要就是两张图的匹配吧(可重叠),因为墙上下可以移动,其实就是匹配轮廓了,完全可以用KMP,KMP第一题纪念一下,果然还是菜啊。
至于KMP感觉这篇博文不错:http://blog.csdn.net/starstar1992/article/details/54913261
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define pi acos(-1)
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
int c[200008],d[200008],ne[200008];
void cal(int w)
{
ne[0]=-1;
int k=-1,i=0;
while(i<w)
{
while(k>-1&&d[k]!=d[i])
{
k=ne[k];
}
if(d[k]==d[i]||k==-1)
{
k++;
}
ne[++i]=k;
}
return;
}
int kmp(int n,int w)
{
int k=0,s=0;
for(int i=0;i<n;i++)
{
while(k>0&&d[k]!=c[i])
{
k=ne[k];
}
if(d[k]==c[i])
{
k++;
}
if(k==w)
{
s++;
k=ne[k];
}
}
return s;
}
int main()
{
int n,w;
while(cin>>n>>w)
{
memset(ne,0,sizeof(ne));
for(int i=0;i<n;i++)
{
c[i]=read();
}
for(int i=0;i<n-1;i++)
{
c[i]=c[i+1]-c[i];
}
for(int i=0;i<w;i++)
{
d[i]=read();
}
for(int i=0;i<w-1;i++)
{
d[i]=d[i+1]-d[i];
}
cal(w-1);
int s=0;
s=kmp(n-1,w-1);
if(w==1)
{
s=n;
}
cout<<s<<endl;
}
return 0;
}
还有HDU2087:http://acm.hdu.edu.cn/showproblem.php?pid=2087(这个是不能重叠的,其实差不多QAQ)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include<iomanip>
using namespace std;
typedef long long ll;
#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define pi acos(-1)
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
int ne[1008];
string c,d;
void cal(int w)
{
ne[0]=-1;
int k=-1,i=0;
while(i<w)
{
while(k>-1&&d[k]!=d[i])
{
k=ne[k];
}
if(d[k]==d[i]||k==-1)
{
k++;
}
ne[++i]=k;
}
return;
}
int kmp(int n,int w)
{
int k=0,s=0;
for(int i=0;i<n;i++)
{
while(k>0&&d[k]!=c[i])
{
k=ne[k];
}
if(d[k]==c[i])
{
k++;
}
if(k==w)
{
s++;
k=-1;
}
}
return s;
}
int main()
{
while(cin>>c)
{
int n,w;
if(c=="#")
{
break;
}
cin>>d;
n=c.size();w=d.size();
memset(ne,0,sizeof(ne));
cal(w);
int s;
s=kmp(n,w);
cout<<s<<endl;
}
return 0;
}
还有洛谷的3375
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%I64d",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod int(1e9+7)
#define pb push_back
#define lc (d<<1)
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
string c,d;
int ne[1000008];
void cal(int w)
{
ne[0]=-1;
int k=-1,i=0;
while(i<w)
{
while(k>-1&&d[k]!=d[i]) k=ne[k];
if(k==-1||d[k]==d[i]) k++;
ne[++i]=k;
}
}
int kmp(int n,int w)
{
int k=0,i=0;
while(i<n)
{
while(k>0&&d[k]!=c[i]) k=ne[k];
if(d[k]==c[i]) k++;
if(k==w) cout<<i-w+2<<endl,k=ne[k];
i++;
}
}
int main()
{
cin.tie(0);
cout.tie(0);
cin>>c>>d;
cal(d.size());
kmp(c.size(),d.size());
cout<<ne[1];
for(int i=2;i<=d.size();i++) cout<<" "<<ne[i];
puts("");
return 0;
}