【题解】洛谷P1081 开车旅行(倍增)

这篇博客详细介绍了如何使用倍增算法解决洛谷P1081题目的100分做法。内容包括预处理城市间可达性,处理边界情况,以及运用倍增数组进行状态转移。博主分享了处理过程中遇到的挑战和简化问题的方法,以及解答题目两问的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这道题目的难度估计是noip之壁了吧。。。

70分的模拟做法之前已经讲过了,现在来说说100分的倍增做法。

首先,读入海拔后,我们可以预处理出从任意一个城市出发, 小A与小B能到达的下一个城市。思路就这么短,但代码非常繁琐,我感觉这部分甚至比倍增还麻烦。我们需要先将城市编号与海拔存在结构体内,对结构体按海拔高低进行排序,然后从1号城市到n号城市寻找其左右相邻的两个城市(还要这样离得最近),判断出来后通过链表记录前驱后继来删除该节点,将每一种情况都考虑到,还要注意是否越界。。。我个人一开始想的太简单,后来一点一点改,不断尝试输出数据直到正确为止,花了我两个半小时。。。这里讲讲能让这部分简单的方法吧。可以将数组的0位和n+1、n+2位设成非常大的数,然后对处在1位置上的数进行特判,这样一来我们的边界情况只用考虑左边界,而且可以解决。我的链表是按照位置存的,排完序后我还开了一个to数组记录某个城市排序后所在的位置。这样在枚举城市时可以直接用to[i]代表当前城市所在位置,而链表又是按照位置存的,相对来说比较方便。处理完这个问题,我们就需要用倍增解决剩下的问题了。我们定义go[i][j]代表从第i号城市出发,经过2^j轮所到达的城市,注意这里的轮是指小A小B都走过了,而且一定是小A先走的。定义A[i][j]代表小A从第i号城市出发,经过2^j轮所经过的路程,B[i][j]代表小A从第i号城市出发后小B走,经过2^j轮所经过的路程。这里的i一定是在一轮内的i,举个例子,go[i][0],i为1,1号城市到2号城市海拔差为6,2号到3号为5,那么A[i][0]=6,B[i][0]=5。明白这一点后,我们需要对倍增数组初始化,go[i][0]就是tb[ta[i]],也就是A走到某个城市后B在这个城市的基础上再走所到达的城市。A[i][0]就是小A从i出发到达城市的海拔减去一开始所在城市海拔的绝对值,B[i][0]就是在某一轮内从i号城市出发,最后到达的城市的海拔减去小A到达的城市的海拔的绝对值(为什么是这样,上面有例子了)。然后我们可以从1-20更新倍增数组,思路和一般的倍增差不多。得到了以上信息,我们就可以回答题目问的问题了。第一问是对于给定的最大路程,求从哪个城市出发小A/小B的值最小。那么我们写一个函数f(start,x),代表从sta

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值