PAT甲级.1033. To Fill or Not to Fill (25)

来源:互联网 发布:ubuntu桌面 编辑:程序博客网 时间:2024/06/05 17:45

题目

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.

输入格式

Each input file contains one test case. 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.

输出格式

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.

输入样例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

输出样例1

749.17

输入样例2

50 1300 12 2
7.10 0
7.00 600

输出样例2

The maximum travel distance = 1200.00


PAT链接


思路

1.将所有加油站存到一个struct里面,并且把终点视为单位油价0,离起点距离D的加油站,然后将所有加油站按离起点的距离从小到大进行排序。
2.设置当前所处加油站编号为cur,接下来将从满油状态下能到达的所有加油站中选出下一个前往的加油站
至于去哪个加油站,策略如下:
1)优先前往更低油价的加油站
即寻找距离当前加油站最近的油价低于当前油价的加油站( 记为k),加恰好能够到达加油站k的油,然后前往加油站k
2)在没有更低油价的加油站时,前往油价尽可能低的加油站
如果找不到油价低于当前油价的加油站,则寻找油价最低的加油站,在当前加油站加满油,然后前往加油站k
3)没有加油站可以到达时,结束算法

代码

version1.0

/*** @tag     PAT_A_1033* @authors R11happy (xushuai100@126.com)* @date    2017-2-11 16:34-19:14* @version 1.0* @Language C++* @Ranking  1060/1281* @function null*/#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;struct Station{    double price;    double dis;}station[550];bool cmp(Station a, Station b){    if (a.dis != b.dis) return a.dis < b.dis;    else return a.price < b.price;}int cur;    //当前到达的加油站号int main(int argc, char const *argv[]){    double cMax, D, dAvg, curTank = 0;    int j, N;    double totalPrice = 0;    scanf("%lf%lf%lf%d", &cMax, &D, &dAvg, &N);    for (int i = 0; i<N; i++)    {        scanf("%lf%lf", &station[i].price, &station[i].dis);    }    sort(station, station + N, cmp);    station[N].price = 0;    station[N].dis = D;    if (station[0].dis > 0)  printf("The maximum travel distance = 0.00\n");    else {        while (cur<N)        {            int minIndex = cur + 1;            int flag = 0;   //结束的标志            for (j = cur + 1; j <= N; j++)            {                // 首先,要满足在当前加油站加满油可以到                if (station[cur].dis + (cMax * dAvg) >= station[j].dis)                {                    flag = 1;                    // 能找到比当前加油站油价低的                    if (station[j].price < station[cur].price)                    {                        flag = 2;                        if ((station[j].dis - station[cur].dis) / dAvg >= curTank)                        {                            totalPrice = totalPrice + station[cur].price*((station[j].dis - station[cur].dis) / dAvg - curTank);                            curTank = 0;                        }                        else    curTank = curTank - ((station[j].dis - station[cur].dis) / dAvg);                        cur = j;                        break;                    }                    else                    {                        if (station[j].price < station[minIndex].price)                        {                            minIndex = j;                        }                    }                }                else                {                    break;                }            }            if (flag == 1)    //找不到加满油范围内比当前加油站油价低的,选择去油价最低的加油站,并在当前加油站加满油            {                totalPrice = totalPrice + station[cur].price*(cMax - curTank);                curTank = cMax - (station[minIndex].dis - station[cur].dis) / dAvg;                cur = minIndex;            }            else if (flag == 0)            {                printf("The maximum travel distance = %.2f\n", station[cur].dis + cMax*dAvg);                break;            }        }        if (cur == N)    printf("%.2f\n", totalPrice);    }    return 0;}

version2.0

/*** @tag     PAT_A_1033* @authors R11happy (xushuai100@126.com)* @date    2017-2-11 16:34-19:14* @version 2.0* @Language C++* @Ranking  1060/1281* @function null*/#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;const int maxn = 510;const int INF = 1000000000;struct station{    double price, dis;  }st[maxn];bool cmp(station a, station b){    return a.dis < b.dis;}int main(int argc, char const *argv[]){    int n;    double cMax, D, dAvg;    scanf("%lf%lf%lf%d", &cMax, &D, &dAvg, &n);    for(int i = 0; i<n; i++)    {        scanf("%lf%lf", &st[i].price, &st[i].dis);    }    // 设置终点为油单价0,距离起点D的加油站    st[n].price = 0;    st[n].dis = D;    // 所有加油站按距离从小到大排序    sort(st, st+n, cmp);    if(st[0].dis != 0)    {        printf("The maximum travel distance = 0.00\n");    }    else    {        int now = 0;    //当前所处的加油站编号        // 总花费、当前油量及满油行驶距离        double ans = 0, nowTank = 0, Max = cMax*dAvg;        while(now < n)  //每次循环将选出下一个需要到达的加油站        {            // 选出从当前加油站加满油能到达范围内的第一个油价低于当前油价的加油站            // 如果没有低于当前油价的加油站,则选择价格最低的那个            int k = -1; //最低油价的加油站编号            double priceMin = INF;  //最低油价            for(int i = now+1; i<=n&&st[i].dis - st[now].dis <= Max; i++)            {                if(st[i].price < priceMin)                {                    priceMin = st[i].price;                    k = i;                    // 如果找到第一个油价低于当前油价的加油站,直接中断循环                    if(priceMin < st[now].price)    break;                }            }            if(k == -1) break;  //满油状态下无法找到加油站,退出循环输出结果            // need为从now到k需要的油量            double need = (st[k].dis - st[now].dis)/dAvg;            // 如果加油站k的油价低于当前油价            if(priceMin < st[now].price)            {                // 只买足够到达加油站k的油                if(nowTank < need)                {                    ans += (need - nowTank)*st[now].price;                    nowTank = 0;                }                else                {                    nowTank -= need;                }            }            else    //如果加油站k的油价高于当前油价            {                ans += (cMax - nowTank)*st[now].price;  //将邮箱加满                nowTank = cMax - need;            }            now = k;    //到达加油站k,进入下一层循环        }        if(now == n) //能到达终点        {            printf("%.2f\n", ans );        }        else        {            printf("The maximum travel distance = %.2f\n", st[now].dis + Max);        }    }    return 0;}

收获

1.intdouble之间相互运算都会变成double类型,所以涉及intdouble之间运算的统一设置为double类型

0 0