4.4 贪心

4.4 贪心

http://codeup.hustoj.com/contest.php?cid=100000584

C To Fill or Not to Fill

image-20200707171611896

题目释义

从杭州开始开车,车内没有油。给定若干加油站信息,问能否驾驶汽车行驶到目的地。若能行驶到目的地,则计算最小花费。若不能,则最远能够行驶多长距离。

给出的第一行数据为,油箱大小Cmax、杭州到目的地距离D、每单位油能行驶的距离Davg、加油站数目N

接下来的N行为各加油站信息,每单位油的价格、加油站离杭州的距离

题目解析

这道题的注意点在于:

  1. 加油时要注意车内可能还有剩余的油。

  2. 若接下来能到达的加油站价格都比现在加油站价格高,不能直接到下一站!!(这里WA了半天),而是要到能到达的相对价格最低的加油站。

    所以在for语句中要记录接下来能到达站点中最低价格的加油站。

首先是审题,从杭州开往目的地,中间有n个加油站,一开始的车没有油,也就是起点必须是加油站,然后寻找加油量最少的站到达,并加油,最后到达目的地,如果两站之间隔得太远不能到,那就在能到的站加满油,走最大距离.

整体分析:

  1. 因为车从杭州出发,给出的加油站信息时加油站离杭州的距离。则假设杭州在起点,d=0。

  2. 将所有加油站按距离排序,从距离为0的起点出发,并把终点标记为离初始点距离为d,油价为0的点(油价为零可以优先被选成终点)

  3. 因为车一开始没有油,则若没有距离为0的加油站,则不能开车,能行驶的距离为0【游戏结束🙃️】

  4. 若能顺利发车,则有以下情况:

    • 在当前加油站能到达的站中,能找到比当前站点油价更低的站点

      则,在当前加油站加刚好能到此站点的油,因为到下一站能加的油更便宜【⚠️若车当前的有够这些,就不用加油了】

    • 若不能找到比当前站点油价更低的站点,就找能到达的 价格相对最低 的站点

      此时要加满油【因为当前站点的油比下一站点的油更便宜】

    • 若根本找不到能到达的站点,则不能到达目的地了,则只能在当前加油站加满油能开多远开多远,故能行驶的最大距离为当前距离+油箱油量*每单位油能到达的距离【游戏结束🙈】

代码

#include <cstdio>
#include <algorithm>

using namespace std;
//假设杭州在起点0
struct station {
    double p;//每升油价格
    double d;//加油站起点位置
} s[505];

bool cmp(station a, station b) {
    if (a.d != b.d) return a.d < b.d;  //按照加油站距离从小到大排
    else return a.p < b.p;  //若距离相同,按照油价从小到大排
}

//贪心 每次都选择最好的
//如果没有第0站则直接到不了,X=0
//若排序后,遍历能到达的加油站,若有比当前站油价便宜的,就在当前站加刚刚好到此站点的油(注意可能原本车里有油)
//若没有比当前站便宜的,也要找一个相对价格最低的!!!(WA:不能直接到下一站),需在当前站加满油
int main() {
    double capacity, distance, d_avg;
    int n;
    while (scanf("%lf %lf %lf %d", &capacity, &distance, &d_avg, &n) != EOF) {
        for (int i = 0; i < n; i++) {
            scanf("%lf %lf", &s[i].p, &s[i].d);
        }
        s[n].p = 0, s[n].d = distance;
        sort(s, s + n + 1, cmp);
        if (s[0].d != 0) {
            printf("The maximum travel distance = 0.00\n");
            return 0;
        }

        int curr_sNo = 0, next_sNo;
        double max_d = capacity * d_avg, curr_capacity = 0, sum_p = 0, temp_minp;
        while (curr_sNo < n) {
            next_sNo = -1; //当前下一站点
            temp_minp = 0x3fffffff;  //当前能找到的最低油价
            // 找出能到达站中最低的油价
            for (int i = curr_sNo + 1; i <= n && s[i].d <= s[curr_sNo].d + max_d; i++) {
                if (s[i].p < temp_minp) {
                    temp_minp = s[i].p;
                    next_sNo = i;
                    //若能找到低于当前油价的加油站,直接选择这个
                    if (temp_minp < s[curr_sNo].p) break;
                }
            }
            //没有能到达的站点,则在当前站点加满油
            if (next_sNo == -1) break;
            else {
                double need = (s[next_sNo].d - s[curr_sNo].d) / d_avg;
                //找到低于当前油价的加油站,则加刚好到达此加油站的油
                if (s[next_sNo].p < s[curr_sNo].p) {
                    if (need > curr_capacity) {
                        sum_p += (need - curr_capacity) * s[curr_sNo].p;
                        curr_capacity = 0;
                    } else {
                        curr_capacity -= need;
                    }
                }
                //没找到低于当前油价的加油站,则在当前加站满油到目前能到达的最低价格油站next_sNo
                else {
                    sum_p += (capacity - curr_capacity) * s[curr_sNo].p;
                    curr_capacity = capacity - need;
                }
                curr_sNo = next_sNo;
            }
        }
        if (curr_sNo < n) printf("The maximum travel distance = %.2f\n", s[curr_sNo].d + max_d);
        else printf("%.2f\n", sum_p);
    }
    return 0;
}

F 迷瘴

image-20200707171855269

题目解析

本题WA点在于计算当前液体和另一瓶液体混合时,当前液体的体积不一定为V。

WA时认为既然每瓶液体的体积都相同为V,则混合后浓度为二者浓度之和/2: tempp = (tempp + p[i]) / 2; 忽略了当前液体可能是混合很多次之后的,即当前液体体积不一定为V。故正确计算为: tempp = (tempp * ansv + p[i] * v) / (ansv + v);

代码

#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

int main() {
    int c;
    int n, v, w, p[105];
    scanf("%d", &c);
    while (c--) {
        scanf("%d %d %d", &n, &v, &w);
        for (int i = 0; i < n; i++) {
            scanf("%d", &p[i]);
        }
        sort(p, p + n);
        if (p[0] > w) printf("0 0.00\n");
        else {
            int i, ansv = v;
            double tempp = p[0], ansp = p[0];
            for (i = 1; i < n; i++) {
                tempp = (tempp * ansv + p[i] * v) / (ansv + v);  //计算浓度要当心!!我以为浓度都是相加/2但是容积不总是相等
                if (tempp > w) break;
                else {
                    ansp = tempp;
                    ansv += v;
                }
            }
            printf("%d %.2f\n", ansv, ansp / 100);
        }
    }
    return 0;
}

本文作者:Joey-Wang

本文链接:https://www.cnblogs.com/joey-wang/p/14541167.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Joey-Wang  阅读(49)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开