【PAT 1033】To Fill or Not to Fill

来源:互联网 发布:mac 桌面隐藏硬盘 编辑:程序博客网 时间:2024/06/14 17:02

题目地址:http://www.patest.cn/contests/pat-a-practise/1033

所用算法:贪心算法

分析:

1. 既然油箱初始为空,那么想要最便宜的方案,到终点的时候,油箱也必须为空。

2. 每个地点的加油策略:

设当前所在位置为 A,则开始寻找下一个加油位置,设为 B,将输入的加油站的位置按照距离的远近进行排序,每次遍历一个加油站。一次性跑的最远的距离为 maxPerTank = Cmax * Davg。

(1) 如果两个相邻的加油站之间的距离大于 maxPerTank,则无法到达终点,本次 case 结束。

(2) 若 B 点的油价低于 A 点,则需要油箱中的油量为可以恰好从 A 点跑到 B 点所需要的油量。

(3) 若 B 点的油价高于 A 点且两点之间的距离小于 maxPerTank,则查看下一个加油站。

(4) 若 B 点的油价高于 A 点但两点之间的距离大于 maxPerTank,则在 A 点加满油,并将 A 和 B 之间油价最便宜的加油站 C 为目的地,到达 C 以后,继续按照从 (2) - (4) 的步骤判断。

源代码(但在 PAT 中有一个测试用例无法通过,希望朋友们看出来代码的问题给我留言):

#include <iostream>#include <vector>#include <algorithm>#include <iomanip>using namespace std;struct Station {    float P;    float Dis;        bool operator < (const Station &a) const {        return Dis < a.Dis;    }};short getMin(vector<Station> st, short begin, short end);int main() {        cout.setf(ios::fixed);    short Cmax = 0, D = 0, Davg = 0, N = 0;    while (cin >> Cmax >> D >> Davg >> N) {        short maxPerTank = Cmax * Davg;        vector<Station> st(N);                // Accept Input        for (short i = 0; i < N; ++i) {            cin >> st[i].P >> st[i].Dis;        }                // 将目的地加入结点        Station des;        des.P = 0.0;        des.Dis = D;        st.push_back(des);                sort(st.begin(), st.end());                // 无法到达        float farthest = 0;        bool isReachable = true;        for (short i = 0; i < N; ++i) {            if (st[i].Dis + maxPerTank < st[i + 1].Dis) {                isReachable = false;                farthest = st[i].Dis + maxPerTank;                break;            }        }        if (!isReachable) {            cout << "The maximum travel distance = " << setprecision(2) << farthest << endl;            continue;        }                // 可以到达,计算最便宜的方案        float sum = 0.0;        float needGas = 0.0;        float nowPos = 0.0;        short i = 1, last = 0;        float priceLast = st[0].P;        float gasLeft = 0.0;                while (i < N + 1) {            if (st[i].Dis - nowPos <= maxPerTank) {                if (st[i].P < priceLast) {                    needGas = (st[i].Dis - nowPos) / Davg;                    if (gasLeft >= needGas) {                        gasLeft -= needGas;                        nowPos = st[i].Dis;                        priceLast = st[i].P;                        last = i;                        ++i;                    } else {                        sum += (needGas - gasLeft) * priceLast;                        gasLeft = 0.0;                        nowPos = st[i].Dis;                        priceLast = st[i].P;                        last = i;                        ++i;                    }                } else {                    ++i;                }            } else {                short minPos = getMin(st, last + 1, i - 1);                sum += (Cmax - gasLeft) * priceLast;                gasLeft = Cmax - (st[minPos].Dis - nowPos) / Davg;                nowPos = st[minPos].Dis;                priceLast = st[minPos].P;                last = minPos;                i = minPos + 1;            }        }                cout << setprecision(2) << sum << endl;    }        return 0;}short getMin(vector<Station> st, short begin, short end) {    short ret = begin;        for (short i = begin; i <= end; ++i) {        if (st[i].P < st[ret].P) {            ret = i;        }    }        return ret;}



希望朋友们多多指教!

0 0
原创粉丝点击