题面描述
思路
这个代码真是又臭又长
思想很简单,相信大家做单调队列应该深有感受了。
就不讲了。
AC code
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define gc getchar()
using namespace std;
const int N=210;
inline void qr(int &x)
{
x=0;int f=1;char c=gc;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc;}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
x*=f;
}
inline void qw(int x)
{
if(x<0)x=-x,putchar('-');
if(x/10)qw(x/10);
putchar(x%10+48);
}
int f[N][N],g[N][N];char s[N];
bool v[N][N];
int q[N],l,r,n,m,x,y,k,st,ed,d;
int main()
{
qr(n),qr(m),qr(x),qr(y),qr(k);memset(g,-1,sizeof(g));memset(f,-1,sizeof(f));
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
for(int j=1;j<=m;j++)
v[i][j]=(s[j]=='x');
}
f[x][y]=0;
while(k--)
{
memcpy(g,f,sizeof(g));
qr(st),qr(ed),qr(d);ed=ed-st+1;
if(d<=2)
{
for(int j=1;j<=m;j++)
{
l=1;r=0;
if(d==1)
{
for(int i=n;i>=1;i--)
{
if(v[i][j]){l=1;r=0;continue;}
while(l<=r&&(q[l]-i)>ed)++l;
while(l<=r&&(g[q[r]][j]==-1||g[q[r]][j]+(q[r]-i)<=g[i][j]))--r;
q[++r]=i;f[i][j]=g[q[l]][j]+(q[l]-i);
}
}
else
{
for(int i=1;i<=n;i++)
{
if(v[i][j]){l=1;r=0;continue;}
while(l<=r&&(i-q[l])>ed)++l;
while(l<=r&&(g[q[r]][j]==-1||g[q[r]][j]+(i-q[r])<=g[i][j]))--r;
q[++r]=i;f[i][j]=g[q[l]][j]+(i-q[l]);
}
}
}
}
else
{
for(int i=1;i<=n;i++)
{
l=1;r=0;
if(d==3)
{
for(int j=m;j>=1;j--)
{
if(v[i][j]){l=1;r=0;continue;}
while(l<=r&&(q[l]-j)>ed)++l;
while(l<=r&&(g[i][q[r]]==-1||g[i][q[r]]+(q[r]-j)<=g[i][j]))--r;
q[++r]=j;f[i][j]=g[i][q[l]]+(q[l]-j);
}
}
else
{
for(int j=1;j<=m;j++)
{
if(v[i][j]){l=1;r=0;continue;}
while(l<=r&&(j-q[l])>ed)++l;
while(l<=r&&(g[i][q[r]]==-1||g[i][q[r]]+(j-q[r])<=g[i][j]))--r;
q[++r]=j;f[i][j]=g[i][q[l]]+(j-q[l]);
}
}
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=max(ans,f[i][j]);
qw(ans);puts("");
return 0;
}