PAT 1033 To Fill or Not to Fill 贪心

With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

Input Specification:
Each input file contains one test case. For each case, the first line contains 4 positive numbers: C
​max
​​ (≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; D
​avg
​​ (≤20), the average distance per unit gas that the car can run; and N (≤ 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: P
​i
​​ , the unit gas price, and D
​i
​​ (≤D), the distance between this station and Hangzhou, for i=1,⋯,N. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print The maximum travel distance = X where X is the maximum possible distance the car can run, accurate up to 2 decimal places.

题解思路:
首先读入所有加油站信息,按照距离排序
从第一个加油站出发(若第一个加油站距离不为0,则哪也去不了),然后依次搜索后面的所能一次性到达的所有加油站,若某个加油站的油价比现在所在的,则继续向后搜索;若某个加油站油价比现在所在的加油站更便宜,则不再搜索,且我们只加够能到达该便宜油价的加油站的油即可,然后更新现在加油站为便宜油价加油站;若没找到更加便宜的,则一次性加满,更新现在加油站为所能到达的最远加油站。

注意

  1. 在一次性加满油箱的情况中,一般到达下一个加油站时会有剩余的油,要考虑进去(这样在下个驻留的加油站可以少加一些)。

  2. 为方便起见,我们将目的地也作为一个加油站(且油价为0),放入加油站的最后

代码

#include <iostream>
#include <stdio.h>
#include<vector>
#include<algorithm>
using namespace std;

struct Gas_Station
{
    int distance;
    double oil_price;
};

bool cmpfun(Gas_Station& a,Gas_Station& b)
{
    if(a.distance<b.distance)
        return true;
    return false;
}

int main()
{
    int capacity,distance,distperunit,sta_num;
    scanf("%d %d %d %d",&capacity,&distance,&distperunit,&sta_num);
    int maxlen = capacity * distperunit;  //加满最多走多远

    vector<Gas_Station> stations(sta_num);
    for(int i = 0;i < sta_num;i++)
    {
        scanf("%lf %d",&stations[i].oil_price,&stations[i].distance);
    }
    sort(stations.begin(),stations.end(),cmpfun);
    Gas_Station dest;
    dest.distance = distance;
    dest.oil_price = 0;
    stations.push_back(dest);
    if(stations[0].distance > 0)  //can go no where
    {
        printf("The maximum travel distance = 0.00");
        return 0;
    }
    double totalcost = 0;
    double remain = 0;
    for(int i = 0;i < sta_num;)
    {
        //cout<<"remain "<<remain<<endl;
        int j = i + 1;
        int next_stop = i;
        bool get_cheaper = false;
        while(true)
        {
            if(j > sta_num || stations[j].distance - stations[i].distance > maxlen)
                break;
            if(stations[j].oil_price > stations[i].oil_price)
            {
                next_stop = j++;  //如果站点j的油价更高 则向后探索,尽量走更远
                //cout<<"next_stop "<<stations[next_stop].distance<<endl;
            }
            else if(stations[j].oil_price <= stations[i].oil_price)
            {
                next_stop = j;  //如果站点j的油价更低 ,则仅加足够到达下一个站点的油量
                get_cheaper = true;
                break;
            }
        }
        //cout<<"next_stop "<<stations[next_stop].distance<<endl;
        if(next_stop == i)  //没有能够到达的下一个站点 说明 i 是最后一次补给
        {
            if(stations[i].distance + maxlen >= distance) //能够到达
            {
                totalcost += stations[i].oil_price * (distance - stations[i].distance)/distperunit;
                printf("%.2f",totalcost);
                return 0;
            }
            else
            {
                double final_len = stations[i].distance + maxlen;
                printf("The maximum travel distance = %.2f",final_len);
                return 0;
            }
        }
        else
        {
            if(get_cheaper == true)
            {
                double needed = (stations[next_stop].distance - stations[i].distance)/(double)distperunit;
                if(remain >= needed)  //油箱所剩大于所需加的油 则不需要加油
                {
                    remain -= needed;
                }
                else
                {
                    needed -= remain;
                    remain = 0;
                    totalcost += stations[i].oil_price * needed;
                }
                i = next_stop;
            }
            else  //一次最大行程中没找到更优惠的加油站,则加满
            {
                totalcost += stations[i].oil_price * (capacity - remain);
                remain = capacity - (stations[next_stop].distance - stations[i].distance)/(double)distperunit;
                i = next_stop;
            }
        }
    }
    printf("%.2f",totalcost);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值