AtCoder Beginner Contest 170 比赛人数10527 比赛开始后4分钟看到A题,在比赛开始后第5分钟看到所有题
AtCoder Beginner Contest 170 F Pond Skater 广度优先遍历BFS+化二维为一维+有一点SPFA算法的味道
总目录详见https://blog.csdn.net/mrcrack/article/details/104454762
在线测评地址https://atcoder.jp/contests/abc170/tasks/abc170_f
题目大意:池上滑冰,因有荷叶阻挡,若不能从出发点到达目的地,打印-1,若能抵达,输出最小行动步数,请注意,每一步,可以在同一方向上滑行[1,k]区间对应的格子数。
基本思路:如果每次只能走1格,该题就是300分的题目,因一次能走多格,曾经熟悉的vis[][]二维数组消失了。该题还有一个难点,0<=h,w<=10^6,二维数组开起来比较麻烦,需采用化二维为一维。
熟悉BFS算法的,该题代码还是容易看懂的,只在模板代码上加了一点点该题特征的代码。
AC代码如下:
#include <stdio.h>
#define maxn 1000010
char mp[maxn],line[maxn];
int d[maxn],r1,c1,r2,c2,H,W,K,next[][2]={{-1,0},{1,0},{0,-1},{0,1}},in[maxn];//UP,DOWN,LEFT,RIGHT,in[]用于记录节点是否在队列中
struct node{
int r,c;
}q[maxn*10];//可能存在某个点重复进入队列,类SPFA算法,故需扩大10倍
int main(){
int i,j,h,t,r,c,nr,nc,p,np;
scanf("%d%d%d",&H,&W,&K);
scanf("%d%d%d%d",&r1,&c1,&r2,&c2),r1--,c1--,r2--,c2--;
for(i=0;i<H;i++){
scanf("%s",line);
for(j=0;j<W;j++)mp[i*W+j]=line[j];//二维化一维
}
for(i=0;i<H;i++)
for(j=0;j<W;j++)d[i*W+j]=maxn;
d[r1*W+c1]=0,h=t=1,q[t].r=r1,q[t].c=c1,t++,in[r1*W+c1]=1;//对起点的初始化,很关键
while(h<t){
r=q[h].r,c=q[h].c,in[r*W+c]=0;
if(r==r2&&c==c2)return 0*printf("%d\n",d[r*W+c]);
for(i=0;i<4;i++)
for(j=1;j<=K;j++){
nr=r+next[i][0]*j,nc=c+next[i][1]*j;
if(0<=nr&&nr<H&&0<=nc&&nc<W){
p=r*W+c,np=nr*W+nc;
if(mp[np]=='@'||d[np]<=d[p])break;//中断j的循环
if(d[np]>=d[p]+1){
d[np]=d[p]+1;
if(!in[np])q[t].r=nr,q[t].c=nc,t++,in[np]=1;
}
}else break;//已越界,终止j的循环
}
h++;
}
printf("-1\n");
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4414119/blog/4318185