KY155 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.

 有了高速公路,开车从杭州到其他任何城市都很容易。但由于汽车的油箱容量是有限的,我们不得不不时地在路上找到加油站。不同的加油站可能会给出不同的价格。你被要求仔细设计最便宜的路线。

输入描述:

For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=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: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,...N. All the numbers in a line are separated by a space.

对于每种情况,第一行包含4个正数:Cmax (<= 100),水箱的最大容量;D (<=30000),杭州到目的地城市的距离;Davg (<=20),汽车每单位汽油行驶的平均距离;N (<= 500)为加油站总数。然后N行,每一行包含一对非负数:Pi,单位汽油价格,Di (<=D),该站到杭州的距离,i=1,…N。一行中的所有数字用一个空格隔开。

输出描述:

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.

对于每个测试用例,在一行中打印最便宜的价格,精确到小数点后两位。假设油箱一开始是空的。如果不可能到达目的地,打印“The maximum travel distance = X”,其中X是汽车可以运行的最大可能距离,精确到小数点后2位。

示例1

输入:

50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
50 1300 12 2
7.10 0
7.00 600

输出:

749.17
The maximum travel distance = 1200.00

 思路

贪心:目标是花费最少,就从“油价”开始“贪”。

  • 将加油站按油价升序排列,依次遍历加油站,
  • 让油价低的加油站出发走尽可能多的路,即走Cmax*Davg(满箱油能走的最大距离),走过的路在路程数组上标记一下,
  • 若从一个加油站出发到最大距离之间有部分已经被走过,则去掉,剩下这段路按该加油站油价收费。

最后若路程数组还有未标记的路段,即没走完,说明不可达。

代码

  • 为了精度更准确,用double储存浮点数,用float测试部分用例会产生误差。
  • C语言保留小数点后两位用printf("%.2lf\n", res); C++用
    //C++ 保留小数点后2位
    cout.setf(ios::fixed);
    cout << setprecision(2) << res << endl;
#include<bits/stdc++.h>
using namespace std;
int main(){
    int Cmax = 0, D = 0, Davg = 0, N = 0;
    double Pi = 0.00;
    int Di = 0;
    multimap<double, int> stations;//加油站:油价 距离
    double res = 0.00;
    while(cin >> Cmax >> D >> Davg >> N){
        stations.clear();
        for(int i = 0; i < N; i++){
            cin >> Pi >> Di;
            stations.emplace(Pi, Di);
        }
        bool* way = new bool[D];//路程数组
        for(int i = 0; i < D; i++)
            way[i] = false;
        /*
        贪心:目标是花费最少,就从“油价”开始“贪”。
        将加油站按油价升序排列,依次遍历,
        让油价低的加油站出发走尽可能多的路,即走Cmax*Davg,走过的路在路程数组上标记一下,
        若从一个加油站出发到最大距离之间有部分已经被走过,则去掉,剩下这段路按该加油站油价收费。
        最后若路程数组还有未标记的路段,即没走完,说明不可达。
        */
        res = 0.00;
        //map默认按油价排序
        for(auto iter = stations.begin(); iter != stations.end(); iter++){
            int dis = 0;//该油站的油所行路程
            for(int i = iter->second; i < iter->second+Cmax*Davg && i < D; i++){
                if(way[i] == false){//未被走过
                    dis++;
                    way[i] = true;
                }
            }
            res += dis * iter->first / Davg;
        }
        //检查路是否走完
        bool finish = true;
        for(int i = 0; i < D; i++)
            if(way[i] == false){//不可达
                cout << "The maximum travel distance = " << i << ".00" << endl;
                finish = false;
                break;
            }
        //保留小数点后两位
        cout.setf(ios::fixed);
        if(finish)cout << setprecision(2) << res << endl;
        
        delete[] way;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值