AtCoder Beginner Contest 170 F Pond Skater 广度优先遍历BFS+化二维为一维+有一点SPFA算法的味道

余生长醉 提交于 2020-08-10 19:31:53

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;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!