1033 To Fill or Not to Fill (25分)

1033 To Fill or Not to Fill (25分)

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

感觉是很复杂的模拟题。。

题意以及思路:

题意是从杭州到某个地方,要途径N个加油站,每个加油站有不同的价格,因此从杭州出发,需要一路加油,如何进行加油可以让总加油耗费最低,如果存在这样的方案,就打印价格,否则就另外输出 无解决方案。。将一路的加油站存入结构体数组i并且按照距离排序,从i->n遍历表示的是一路的加油站。。刚开始汽车没有油,然后起点是一定要有加油站的,假设当前的加油站为下标为0,nowstation,然后去当前加油站加满油 能够达到的最远位置及之前查找下一站。分三种情况讨论:1,有比我价格更低的加油站smlerstation,直接开到下一站,立马换油,那么此时到达smlerstation位置的加油的距离减去的nowstation的距离就是我用nowstation的价格开的距离,然后计算对应的耗费。。2,没比我更低价格的加油站,那么我在这个距离内,肯定要找到一个加油站进行加油,以行驶更远的距离。因此,我们需要在后面能够到达的距离范围内,找到价格最低的那个加油站,位置为secsmalerpos。由于nowstation的价格比我现在的secsmalerpos价格底,因此我们需要将nowstation加的油最大化,因此我们为nowstation设置一个变量secdi,记录nowstation对应的能够到达的最大位置,同时,计算nowstation加多少油对应的耗费。其中一种形式是,上次找不到更小价格,这次还找不到更小价格,那么就用这次最大能够到达的距离减去上次能够达到的最大距离,计算对应耗费;如果上次找不到最小价格,这次找到了最小价格,那么价格计算就应该这次的加油站距离减去上次记录的secdi,即得到上次加油站的油真实行驶的距离,再计算耗费。。

3,如果不能够找到,说明没法到达更远的距离了,当前的能够达到距离即为最远距离,用maxcanto记录。

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+20;
const int inf=1e9+10;
int cmax,d,davg,n;
double maxcanto=0;
struct Node
{
    double pi;
    double di;
    double secdi;
};
Node nd[maxn];
bool cmp(Node a,Node b)
{
    if(a.di == b.di)return a.pi<b.pi;
    else return a.di<b.di;
}
int main()
{
    cin>>cmax>>d>>davg>>n;
    for(int i=0;i<n;i++)
    scanf("%lf %lf",&nd[i].pi,&nd[i].di);
    nd[n].di = d;
    nd[n].pi = 0;
    n = n+1; //将最后终点站当作是一个加油站,价格为0.
    sort(nd,nd+n,cmp);
    int nowstation = 0,laststation = 0;
    double canto = double(nd[nowstation].di+cmax*davg);
    double cost=0;
    if(nd[nowstation].di>0)
    {
        printf("The maximum travel distance = 0.00\n");
    }else
    {
        //寻找在nowstation完全加满油能够到达的所有加油站中最近的更低价格的下一站
        // 1.范围内有更低价格的加油站,将当前距离移动到下一个站点,计算之前站到当前站的花费油钱
       int ff=0;
       while(1)
       {
       canto = double(nd[nowstation].di+cmax*davg);
       if(canto>maxcanto)maxcanto = canto;
       int smalerpos = -1,secsmalerpos = -1;
       double minpi = double(inf);

       for(int i=nowstation+1;i<n&&nd[i].di<=canto;i++)
       {
            if(nd[i].pi<nd[nowstation].pi&&smalerpos==-1)
            {
                smalerpos = i;
                //break;
            }
            if(nd[i].pi<minpi)
            {
                minpi = nd[i].pi;
                secsmalerpos = i;
            }
       }
       if(smalerpos !=-1)
       {
           //到下一站就用完油,计算耗费
          // cout<<"nd[nowstation].secdi=== "<<nd[nowstation].secdi<<endl;
           if(nd[nowstation].secdi!=0)
           {
               cost+=double((nd[smalerpos].di-nd[nowstation].secdi)/davg*nd[nowstation].pi);
           }
           else
           cost+=double((nd[smalerpos].di - nd[nowstation].di)/davg*nd[nowstation].pi);
           laststation = nowstation;
           nowstation = smalerpos;
       }else if(secsmalerpos!=-1)
       {
           //后面的站的油价都比我当前的高,所以找后面的油价相比最低的
           //上次的油价比我这次底,那就让上次的油加满,
           //cout<<"nd[nowstation].secdi:: "<<nd[nowstation].secdi<<endl;
            if(nd[nowstation].secdi!=0)
            {
                cost+=double(((nd[nowstation].di+cmax*davg-nd[nowstation].secdi))/davg*nd[nowstation].pi);
            }else
            {
                cost+=double((cmax*nd[nowstation].pi));
            }

           laststation = nowstation;
           nowstation = secsmalerpos;
           nd[nowstation].secdi = nd[laststation].di+cmax*davg;
       }else
       {
           //说明无法到达终点,因为在当前站的后面,没有油价比我小的加油站,也没有比我大的。
           break;
       }
       //cout<<"smalerpos: "<<smalerpos<<"  secsmalerpos: "<<secsmalerpos<<endl;
       //printf("  cost: %.2lf ,  canto: %.2lf\n",cost,canto);
        if(nowstation == n-1)
        {
            //说明到达了终点
            ff=1;
            break;
        }
       }
       if(ff)
       {
           printf("%.2lf\n",cost);
       }else
       {
           printf("The maximum travel distance = %.2lf\n",maxcanto);
       }


    }

    return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值