【PAT A1030】To Fill or Not to Fill

在这里插入图片描述
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

解题思路:
这题是目前为止我觉得最复杂的题,调了很久。思路稍稍想想还是有的。首先将加油站按照距离从近到远排序肯定是要的,在这之后题中无非包括两个过程,第一个过程是判断在当前加油站要加多少油,第二个过程是下一次去哪个加油站,而判断下一次去哪一个加油站决定了在当前加油站要加多少油,这两个过程需要循环进行(大循环)。至于判断下一次去哪一个加油站就需要从当前加油站开始依次向后找如果装满油能到达的路程中比当前加油站便宜的站点(此时加能到达这个便宜的加油站的油就好了,其他的到了那里再说,毕竟这里的油要便宜一些),如果找不到比当前加油站便宜的站点,那么就加满油去到能到达的比当前加油站贵但比加满油能跑的路程中的其他加油站便宜的站点。详细的可以看代码,我已经尽量写注释了,希望能帮到大家。说到底,还是菜~

#include <cstdio>
#include <algorithm>
using namespace std;

struct station
{
    double distance;
    double price;
} stat[510];

bool compare(station A, station B)
{
    return A.distance < B.distance;
}

int main()
{
    double tankCap, dist, cons;
    int numStation;
    scanf("%lf%lf%lf%d", &tankCap, &dist, &cons, &numStation);
    for (int i = 0; i < numStation; i++)
        scanf("%lf%lf", &stat[i].price, &stat[i].distance);
    //把终点也加数组
    stat[numStation].price = 0;
    stat[numStation].distance = dist;
    sort(stat, stat + numStation + 1, compare); //按距离顺序排序

    int current = 0, next;           //current为当前所在的加油站,next是要去的下一个加油站,far能取得最远的加油站
    double onceDis = cons * tankCap; //油箱加满一次能跑多远
    int min = -1;                    //加满油能跑的路上比当前加油站贵但比其他加油站便宜
    double remain = 0;               //当前剩余油量
    double totalcost = 0;
    //如果第一个站点的distance不为0则走不了,坑点
    if (stat[current].distance != 0)
    {
        printf("The maximum travel distance = 0.00\n");
        return 0;
    }
    while (current != numStation)
    {
        //一直往后找直到能到达的最优点
        min = -1; //每个循环都要重新设定
        next = current + 1;
        while (stat[next].distance - stat[current].distance <= onceDis)
        {
            //找到了比当前加油站更便宜的加油站
            if (stat[next].price < stat[current].price)
            {
                break;
            }
            //记录第二便宜的加油站的位置(当前站点是最便宜的)
            else
            {
                if (min == -1 || stat[next].price < stat[min].price)
                    min = next;
                next++;
            }
        }
        //即使加满油连相邻站点都到不了
        if (stat[current + 1].distance - stat[current].distance > onceDis)
        {
            printf("The maximum travel distance = %.2lf\n", stat[current].distance + onceDis);
            return 0;
        }
        else
        {
            double add;
            //比较next和min位置的油价格,以确定要去的下一位置,弹药注意min可能等于-1(未修改过)
            //当找不到比当前便宜的时,跳出while循环后next为能到的最远站的index+1
            if (stat[next].distance - stat[current].distance <= onceDis && stat[next].price < stat[min > 0 ? min : current].price)
            {
                //只需加能到达下一站的油量即可,甚至油量够就不用加
                if (remain < (stat[next].distance - stat[current].distance) / cons)
                    add = (stat[next].distance - stat[current].distance) / cons - remain;
                else
                    add = 0;
            }
            else
            {
                add = tankCap - remain; //加满油,毕竟min位置的油价要比当前位置要高
                next = min;
            }
            remain += add;
            totalcost += add * stat[current].price;
            remain -= (stat[next].distance - stat[current].distance) / cons; //减去到下一站的油
            current = next;                                                  //当前站点修改为该便宜加油站
        }
    }
    printf("%.2lf\n", totalcost);

    return 0;
}


发布了30 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/lvmy3/article/details/103916692