http://codeforces.com/contest/1064/problem/D
向上/向下加0,向左/右加1,
step = 0,1,……
求的是最少的步数,所以使用bfs。
step=k -> step=k+1
1.step=k 使用一次左/右 到达 step=k+1
2.step=k+1 无限使用上下,得到所有 step=k+1 的状态
用dijkstra+堆优化 / spfa 超时。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define minv 1e-6
#define inf 1e9
#define pi 3.1415926536
#define nl 2.7182818284
const ll mod=1e9+;//
const int maxn=(2e3+)*(2e3+); int q[maxn],step[maxn];
char s[maxn];
int n,m,bx,by,gl,gr,head,tail,phead,i,sum=,l,r,d; void add(int d,int pos,int k)
{
tail++;
q[tail]=d;
s[d]='*';
step[tail]=step[pos]+k;
r=(d%m-by+step[tail])/;
l=step[tail]-r;
if (l<=gl && r<=gr)
sum++;
} int main()
{
scanf("%d%d",&n,&m);
scanf("%d%d",&bx,&by);
scanf("%d%d",&gl,&gr);
bx--,by--,sum++;
q[]=bx*m+by;
for (i=;i<=n;i++)
scanf("%s",s+(i-)*m);
s[q[]]='*';
head=,tail=;
while (head<=tail)
{
phead=head;
while (head<=tail)
{
d=q[head]-m;
if (d>= && s[d]=='.')
add(d,head,);
d=q[head]+m;
if (d<n*m && s[d]=='.')
add(d,head,);
head++;
}
//[phead,tail] (head-1)
while (phead<head)
{
d=q[phead]-;
if (d%m!=m- && s[d]=='.')
add(d,phead,);
d=q[phead]+;
if (d%m!= && s[d]=='.')
add(d,phead,);
phead++;
}
}
printf("%d",sum);
return ;
}