[ PAT-A ] 1033 To Fill or Not to Fill (C++)

题目描述

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.

Sample Input 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

Sample Output 1:
749.17

Sample Input 2:
50 1300 12 2
7.10 0
7.00 600

Sample Output 2:
The maximum travel distance = 1200.00


解题思路

题目大意
车要从起点开向终点,但是由于油箱容量有限,须在中途加油,因此途中将设立多个加油站,如何加油才可使路上所耗油费最低.
如若车因油量不足无法到达终点,只须输出可行驶的最远距离
思路


  • 起始点须有加油站,因为车刚开始油箱为空
  • 寻找下一加油站B.在油箱满的情况下,从此时的加油站A出发,在不加油的情况下,依次遍历可行驶的最远距离内所有的加油站
    (1)若在此范围内,无加油站,表明无法行至终点,只须求可行驶的最远距离
    (2)若有加油站,应按距离的远近与此时的加油站A进行油价判断,第一个油价小于A油价的加油站为下一个加油地点B,并且在A加油时应保证车可以刚刚好开驶至B加油站;如若没有加油站的油价低于A处的,则选出此范围内油价最低的加油站为下一加油地点B,而在A处加油时,将油箱加满即可.


    代码设计
    //AC代码
    //zhicheng
    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    // zhicheng
    // August 16,2018
    typedef struct{float pri;float dis;}D;
    float c,d,da;int n;
    vector<D> a;
    
    bool comp(D a,D b){return a.dis<b.dis;}
    
    int fun(int k)
    {// 寻找下一加油站地点
        int cnt=0;float minpri=0;
        if(a[k+1].dis>a[k].dis+c*da) return -1;
        for(int i=k+1;i<=n&&a[i].dis<=a[k].dis+c*da;i++)
        {
            if(minpri==0||minpri>a[i].pri) {cnt=i;minpri=a[i].pri;}
            if(a[i].pri<a[k].pri) return i;
        }
        return cnt;
    }
    int main()
    {
        // freopen("1.txt","r",stdin);
        float best_pri=0;D tmp;float distance;
        scanf("%f %f %f %d",&c,&d,&da,&n);
        for(int i=0;i<n;i++) {scanf("%f %f",&tmp.pri,&tmp.dis);a.push_back(tmp);}
        tmp.dis=d;tmp.pri=0;a.push_back(tmp); // 将终点纳入加油站行列,只不过油价为0
        sort(a.begin(),a.end(),comp);
        if(a[0].dis!=0) {printf("The maximum travel distance = 0.00\n");return 0;}// 如若起点无加油站,则车无法开驶至任何地方
        int cn;double cmax=0;
        for(cn=0;cn<n&&cn!=-1;) 
        {
            int start=cn;
            cn=fun(cn);
            if(cn==-1) 
            {// 下一加油站太远,油量不够
                distance=a[start].dis+c*da;
                break;
            }
            if(a[start].pri<a[cn].pri)
            {// 下一加油站油价大于此次加油站的,则在此加满油
                best_pri+=a[start].pri*(c-cmax);
                cmax=c-(a[cn].dis-a[start].dis)/da;
            }
            else
            {// 下一加油站油价不大于此次加油站的,则保证车刚刚好可以开驶至下个油站
                best_pri+=a[start].pri*((a[cn].dis-a[start].dis)-cmax*da)/da;
                cmax=0;
            }
        }
        if(cn==-1) printf("The maximum travel distance = %.2f\n",distance);
        else printf("%.2f\n",best_pri);
        return 0;
    }


    有关PAT (Basic Level) 的更多内容可以关注 ——> PAT-B题解


    有关PAT (Advanced Level) 的更多内容可以关注 ——> PAT-A题解

    铺子日常更新,如有错误请指正
    传送门:代码链接 PTA题目链接 PAT-A题解

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值