PAT (Advanced) 1033. To Fill or Not to Fill (25)

原题:1033. To Fill or Not to Fill (25)


解题思路:

贪心法。每在一个站都有如下情况:

1)刚出发时,第一个加油站不在0点,直接退出;

2)从当前加油站的后一个加油站在行驶距离内开始向前搜索,比较价格,直到找到价格比当前低的第一个加油站或者后续加油站中最便宜的;

3)找到的加油站价格比当前高,先检查能否直接到达目的地, 若能,加足够抵达的油即可,在当前加油站加满油,开到找到的加油站;

4)找到的加油站价格比当前低,加足够到达找到的加油站的油即可;

5)如果没找到,那就判断当前加油站能否到达目的地,能就到达目的地,不能就输出最大距离;

代码如下:


#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 500 + 5;
int n;
double c, dist, davg;
struct station
{
    double dist;
    double price;
    bool operator < (const station& rhs) const
    {
        return dist < rhs.dist;
    }
} sta[maxn];

void solve()
{
    double maxDrive = c * davg;
    int pos = 0, flag = 0;//flag 标记能否到达
    double cost = 0, d = 0, remain = 0;// remain表示剩余油量
    for(;;)
    {
        if(sta[0].dist != 0) break; //第一个加油站无法抵达
        int u = -1;
        double price = 1e20;
        for(int i = pos + 1; i < n && sta[i].dist <= sta[pos].dist + maxDrive; i++)
        {//寻找后面价格最低的加油站
            if(price > sta[i].price)
            {
                price = sta[i].price;
                u = i;
            }
            if(price < sta[pos].price) break; //已经比当前低了,退出查找
        }
        if(u == -1) //没有找到合适的加油站
        {
            if(d + maxDrive >= dist) //可到达目的地
            {
                flag = 1;
                cost += ((dist - sta[pos].dist)/davg - remain) * sta[pos].price;
                remain = 0;
            }
            d += c * davg;
            break;
        }
        if(sta[u].price > sta[pos].price) //找到的油价高于当前
        {
            if(d + maxDrive >= dist) //能抵达
            {
                flag = 1;
                cost += ((dist - sta[pos].dist)/davg - remain) * sta[pos].price;
                remain = 0;
                break;
            }
            else //不能抵达, 把油加满并减去开到找到的加油站的油
            {
                d = sta[u].dist;
                cost += (c - remain)*sta[pos].price;
                remain = c - (sta[u].dist - sta[pos].dist)/davg;
                pos = u;
            }
        }
        else //低于当前油价,直接开往找到的加油站
        {
            d = sta[u].dist;
            cost += ((sta[u].dist - sta[pos].dist)/davg - remain) * sta[pos].price;
            remain = 0;
            pos = u;
        }
    }
    if(flag) printf("%.2f\n", cost);
    else printf("The maximum travel distance = %.2f\n", d);
}

int main()
{
    while(scanf("%lf%lf%lf%d", &c, &dist, &davg, &n) == 4)
    {
        for(int i = 0; i < n; i++)
        {
            double d, p;
            scanf("%lf%lf", &p, &d);
            sta[i].dist = d;
            sta[i].price = p;
        }
        sort(sta, sta+n);
        solve();
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值