PAT A1033 To Fill or Not to Fill 加不加油(贪心)

这道题就是一整个吸烟刻肺 刻苦铭心

需要注意输出为double类型 参与运算的数据最好都是double 不然容易四舍五入把小数部分舍去,从而结果出现误差。

开始把距离存int 一直不对 多次调试找出问题所在

还有一个需要注意的点是 要把终点也存进vector中

这样才能判断是否能够到达终点 并且输出正确的值

算法分析:

这道题目可以使用贪心算法解决。我们可以按照距离从小到大的方式,将加油站排序,并从起点出发。每次选择能够到达的范围内价格最低的加油站加满油,然后前往该加油站。当无法到达目标加油站时,输出最远能够行驶的距离。如果能够到达终点,则到达终点后输出总花费。

具体实现:

我们可以使用 vector 存储加油站信息,包括距离和油价。然后将加油站按照距离从小到大排序。接着,从起点开始,每次选择能够到达的范围内价格最低的加油站加满油,然后前往该加油站。如果无法到达目标加油站,则输出最远能够行驶的距离。如果能够到达终点,则到达终点后输出总花费。

ac代码如下 :

长长的57行都是我的眼泪。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<pair<double,double>> sta; // 存储加油站信息
int main()
{
    int v,dis,m,n;
    cin>>v>>dis>>m>>n;
    int maxnum=v*m; // 最大行驶距离
    while(n--)
    {
        double money,x;
        cin>>money>>x;
        sta.push_back({x,money});
    }
    sta.push_back({dis,0}); // 将终点也看作一个加油站
    double res=0,oil=0; // res 存储总花费,oil 存储当前油量
    sort(sta.begin(),sta.end()); // 将加油站按距离从小到大排序
    if(sta[0].first!=0) // 如果起点没有加油站,则无法行驶
    {
        cout<<"The maximum travel distance = 0.00";
        return 0;
    }
    for(int i=0;i<sta.size()-1;) // 循环处理每个加油站
    {
        int k=-1;
        for(int j=i+1;j<sta.size()&&sta[j].first-sta[i].first<=maxnum;++j) // 在能够到达的范围内选择加油站
        {
            if(sta[j].second<=sta[i].second) // 如果新的加油站的油价比当前加油站的油价低,则选择它
            {
                k=j;
                break;
            }
            else if(k==-1||sta[k].second>sta[j].second) // 否则选择油价最低的加油站
                k=j;
        }
        if(k==-1) // 如果无法到达目标加油站
        {
            printf("The maximum travel distance = %.2lf",sta[i].first+(double)maxnum);
            return 0;
        }
        else if(sta[k].second<=sta[i].second) // 如果目标加油站的油价比当前加油站的油价低,则加油
        {
            res+=((sta[k].first-sta[i].first)/m-oil)*sta[i].second; // 计算花费
            i=k,oil=0; // 更新当前位置和油量
        }
        else // 否则前往目标加油站
        {
            res+=(v-oil)*sta[i].second; // 计算花费
            oil=v-(sta[k].first-sta[i].first)/m; // 更新油量
            i=k;
        }
    }
    printf("%.2lf",res); // 输出总花费
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值