PAT (Advanced Level) Practice 1033 To Fill or Not to Fill题解

文章讲述了如何使用贪心策略解决PAT甲级1033问题,即在给定多个加油站和油价条件下,找到从起点到终点花费最少的加油策略。作者详细描述了解题思路并给出了Python代码示例,指出还有优化空间。
摘要由CSDN通过智能技术生成

PAT甲级1033是一道复杂的贪心问题,写篇题解记录一下解题过程。这题的大致意思是从出发地A到目的地B中有若干个加油站,每个加油站都有自己的油价,怎么选择加油策略能使从A到B花费最少的价格。原题网址:PTA | 程序设计类实验辅助教学平台

如何使用贪心策略解决这个问题呢?首先我们假设车辆来到了中间的某一加油站X,剩余油量是C,那么我们要做的是寻找X之后最近的油价低于X的加油站,如果存在该加油站Y,则需要判断X到Y是否能直接到达(也就是中间不再加油),如果可以那么在X把油量补充到能恰好到达Y的油量,如果不能则直接把油加满。

以上这一段就是贪心策略的关键,也就是尽可能保证车辆能够到达油价更低的加油站加油,但是如果油价更低的加油站距离太远无法直达,换句话说在车辆一箱油可达的路程里没有比当前加油站油价更低的加油站,那么就在当前加油站把油加满能获得最大的利益。当然还有一种情况是之后没有比当前加油站油价更低的加油站Y存在,那么当前加油站X就是之后所有加油站里油价最低的加油站,直接在此加油站把油加满就能获得最大利益。

如果要写代码的话,以上的叙述中还有许多细节需要注意,比如距离目的地够近的时候来到油价最低的加油站并不需要把油加满,而是加至能够恰好到达目的地的油量就可。详细的逻辑结构可以总结为:

##读入数据
##依次经过每一个车站
        ##判断当前油箱容量是否能直接到达目的地,若能则计算总价跳出循环
        ##如不能,寻找当前油站之后油价比当前油站更低的油站j

                ##j存在
                        ##j是否能够在加满油的情况下直接到达,若能将油箱添加至刚好能到达j的油量
                        ##若不能,则直接加满油箱
                ##j不存在
                        ##判断满油是否能到达目的地,若能则将油箱加至恰好能到达目的地的油量
                        ##如不能直接将油箱加满
        ##加油完毕,行驶到下一个加油站或终点
                ##最后一个加油站

                        ##行驶到终点
                ##不是最后一个加油站
                        ##可以行驶到下一个加油站

根据这种思路,写出代码:

##读入数据
import sys
class gas:
    def __init__(self,price,distance):
        self.price=float(price)
        self.distance=float(distance)

line1=input().split()
cap=int(line1[0])
dis=int(line1[1])
avg=int(line1[2])
n=int(line1[3])
gases=[]
for i in range(n):
    line2=input().split()
    g=gas(line2[0],line2[1])
    gases.append(g)
gases=sorted(gases,key=lambda gas:gas.distance)
if gases[0].distance!=0:
    print("The maximum travel distance = 0.00")
    sys.exit()
CurrentPrice=0
CurrentCap=0
##依次经过每一个车站
for i in range(n):
    DisFromNowToFin = dis - gases[i].distance
    ##判断当前油箱容量是否能直接到达目的地,若能则计算总价跳出循环
    if CurrentCap*avg>=DisFromNowToFin:
        CurrentPrice=f"{CurrentPrice:.2f}"
        print(CurrentPrice)
        break
    ##如不能,寻找当前油站之后油价比当前油站更低的油站j
    else:
        j=-1
        for k in range(i+1,n,1):
            if gases[k].price<=gases[i].price:
                j=k
                break
        ##j存在
        if j!=-1:
            DisFromIToJ=gases[j].distance-gases[i].distance
            CapFromIToJ = DisFromIToJ / avg
            maxDis=avg*cap
            ##j是否能够在加满油的情况下直接到达,若能将油箱添加至刚好能到达j的油量
            if DisFromIToJ<=maxDis:
                 if CapFromIToJ>CurrentCap:
                     Input=CapFromIToJ-CurrentCap
                     CurrentCap+=Input
                     CurrentPrice+=Input*gases[i].price
            ##若不能,则直接加满油箱
            else:
                Input=cap-CurrentCap
                CurrentCap+=Input
                CurrentPrice+=Input*gases[i].price
        ##j不存在
        else:
            DisFromIToFin=dis-gases[i].distance
            CapFromIToFin=DisFromIToFin/avg
            maxDis = avg * cap
            ##判断满油是否能到达目的地,若能则将油箱加至恰好能到达目的地的油量
            if DisFromIToFin<=maxDis:
                if CapFromIToFin>CurrentCap:
                    Input=CapFromIToFin-CurrentCap
                    CurrentCap+=Input
                    CurrentPrice+=Input*gases[i].price
            ##如不能直接将油箱加满
            else:
                Input=cap-CurrentCap
                CurrentCap+=Input
                CurrentPrice+=Input*gases[i].price

    ##行驶到下一个加油站或终点
    if i==n-1:
        ##最后一个加油站
        DisFromIToNext=dis-gases[i].distance
        MaxCapDis = CurrentCap * avg
        if DisFromIToNext>MaxCapDis:
            ##无法行驶到终点
            maxDis=gases[i].distance+MaxCapDis
            maxDis=f"{maxDis:.2f}"
            print(f"The maximum travel distance = {maxDis}")
            break
        else:
            ##行驶到终点
            CurrentPrice = f"{CurrentPrice:.2f}"
            print(CurrentPrice)
            break
    else:
        ##不是最后一个加油站
        DisFromIToNext=gases[i+1].distance-gases[i].distance
        MaxCapDis=CurrentCap*avg
        if DisFromIToNext>MaxCapDis:
            ##无法行驶到下一个加油站
            maxDis=gases[i].distance+MaxCapDis
            maxDis=f"{maxDis:.2f}"
            print(f"The maximum travel distance = {maxDis}")
            break
        else:
            ##可以行驶到下一个加油站
            CurrentCap-=DisFromIToNext/avg

写完这题之后我觉得代码还有很多优化空间,比如不需要把加油站和终点区别对待,而是把终点看做一个油价为0的加油站,有时间可以继续优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值