Tsinsen A1122 旅行家的预算

来源:互联网 发布:基于stack的列表 java 编辑:程序博客网 时间:2024/05/28 20:18

http://oj.tsinsen.com/ViewGProblem.page?gpid=A1122

分析:浮点精度和一些边界条件弄得我心惊胆战的。这个题从算法来说不难,先读入输入,按顺序一个一个经过站点(将起点标记为0, 终点标记为n+1),成功经过站点则将其加入【待选加油序列】——这里根据的是经过某一站点,在当时加油和以后判断需要加油时“穿越”回去加油在逻辑上是等价的。加油序列按照油价排序,每次都加至刚好能到下一节点,并注意保存在某油站加过的油量——因为一旦这个值超过油箱容量,则不能再在这个站点加油。其他一些细节,比如判断“No Solution”之类的,看看代码就可以了。

代码:

#include "cstdio"#include "vector"#include "algorithm"using namespace std;struct Node { double d, p, c; }s[10050];bool f(const Node & a, const Node & b) { return a.d < b.d; }bool h(const Node & a, const Node & b) { return a.p > b.p; }vector < Node > q;int main() {    bool Can = true;    double d1, c, d2, cost = 0;    int n;    scanf("%lf%lf%lf%lf%d", &d1, &c, &d2, &s[0].p, &n);    s[0].d = 0;    for (int i = 1; i <= n; ++i)        scanf("%lf%lf", &s[i].d, &s[i].p);    s[n + 1].d = d1; s[n + 1].p = 0;    sort(s, s + n + 2, f);    for (int i = 0; i <= n + 1; ++i)        s[i].c = 0;    q.push_back(s[0]);    for (int i = 1; i <= n + 1; ++i) {        double dist = s[i].d - s[i - 1].d;        double need = dist / d2;        if (need > c) { Can = false; break; }        while (need > 0) {            if (q[q.size() - 1].c > c) q.pop_back();            if (need - (c - q[q.size() - 1].c) < 0) {                cost += need * q[q.size() - 1].p;                q[q.size() - 1].c += need;                break;            }            else {                cost += (c - q[q.size() - 1].c) * q[q.size() - 1].p;                need -= (c - q[q.size() - 1].c); q.pop_back();            }        }        q.push_back(s[i]); sort(q.begin(), q.end(), h);    }    if (Can) printf("%.2lf\n", cost);    else puts("No Solution");    return 0;}
0 0
原创粉丝点击