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

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值