1033. To Fill or Not to Fill (25)

来源:互联网 发布:离线下载软件 知乎 编辑:程序博客网 时间:2024/06/13 04:55

1.这道题目比较有趣,给出了加油站的位置和每个站的油价,求最小耗费,如果不能到达终点,则求能走的最远距离

2.思路:

1)采用一个油箱数组的概念,实则是一个vector,当成队列使用,这个vector记录了加了的油的价格,油的容量,通过这些油走过的长度和耗费;

2)每到一个站,计算从上一站达到这个站所需要的油needGas

3)从油箱数组容量不为0的油中开始遍历,直接完全满足needGas的要求,同时计算油箱数组中被使用到的油的耗费和走的距离。

4)遍历完油箱数组后,如果needGas不为0,那么油箱数组的总油量不够用,直接计算油箱数组走的总距离并输出答案

5)如果needGas为0,那么对比油箱数组剩余油(油的容量不为0)的价格,如果比当前站高,则更新为当前站的价格,

其实际意义是:到了当前的加油站,油箱里面还有油(这些油可加也可不加,都能使车到达当前站点),这些油的价格比当前加油站要高(那么之前就没必要加油,直接在当前站点加满),那么在之前就不加油了,在这个站点家满cMax的油量,记录价格,进入下一次循环即可。

6)把终点作为最后一个站,油的价格为0.


AC的代码如下,有详细解释:

//#include<string>//#include <iomanip>#include<vector>#include <algorithm>//#include<stack>#include<set>#include<queue>#include<map>//#include<unordered_set>#include<unordered_map>//#include <sstream>//#include "func.h"//#include <list>#include<stdio.h>#include<iostream>#include<string>#include<memory.h>#include<limits.h>using namespace std;/*50 1300 12 86.00 12507.00 6007.00 1507.10 07.20 2007.50 4007.30 10006.85 30050 1300 12 27.10 07.00 60050 0 12 27.10 07.00 60050 0 12 050 13000 12 27.10 07.00 600*/struct stationNode{float price;int position;stationNode() :price(0), position(0){};};struct gasNode{float price;//价格float cap;//容量float cost;//总价格float dist;gasNode() :price(0), cap(0), cost(0),dist(0){};gasNode(float p,float c) :price(p), cap(c), cost(0),dist(0){};};bool cmp(const stationNode&a, const stationNode&b){return a.position < b.position;}int main(void){int cMax, target, dAvg, n;cin >> cMax >> target >> dAvg >> n;n++;//把终点也作为一个站vector<stationNode> sta(n);for (int i = 0; i < n - 1; i++){//初始化cin >> sta[i].price >> sta[i].position;}sta.back().position = target;//设置终点的距离sort(sta.begin(), sta.end(), cmp);//按照站的位置进行排序vector<gasNode> gas(0);//油箱数组int gasIndex = 0;//记录当前用到哪个油箱数组的油float totalGas = 0;if (0 >= sta[0].position){//把第一个站加进去,包含价格信息和加了多少油gas.push_back(gasNode(sta[0].price, cMax));totalGas = cMax;//now += cMax*dAvg;}for (int now = 1; now < n; now++){//needGas表示从i-1站到i站需要多少油float needGas = (sta[now].position - sta[now - 1].position) *1.0 / dAvg;//把油箱里的油减去需要用的油,计算得到油箱还剩多少油totalGas -= needGas;//在这里可以直接判断totalGas是否小于0,小于0表示油箱不够油跑下去,但是由于题目还需要求最长距离,所以这里不作处理,统计完邮箱所有的油再进行处理//遍历邮箱数组,利用gasIndex做开始位,减少时间复杂度for (int j = gasIndex; j < gas.size(); j++){if (gas[j].cap > needGas){//当前vector的油能够满足需求gas[j].cap -= needGas;//减去需要用的油,得到剩余的油gas[j].cost += needGas*gas[j].price;//计算这个vector的油已经耗费了多少钱gas[j].dist += needGas*dAvg;//计算这个vector的油走了多长的路gasIndex = j;//下次直接从这个vector计算油量needGas = 0;break;}else if (gas[j].cap < needGas){//如果当前vector的油量不足gas[j].cost += gas[j].cap*gas[j].price;//计算这个vector的油耗费了多少钱gas[j].dist += gas[j].cap*dAvg;//计算这个vector的油走了多长的路needGas -= gas[j].cap;//除去这个vector的油,还需要多少油gasIndex = j;}else{//刚好等于需要的油,由于使用了float,基本不会出现这种needGas等于0的情况gas[j].cost += gas[j].cap*gas[j].price;//计算这个vector的油耗费了多少钱gas[j].dist += gas[j].cap*dAvg;//计算这个vector的油走了多长的路needGas -= gas[j].cap;//needGas为0gasIndex = j + 1;//直接指向下个vectorbreak;}}if (needGas > 0){//当前油箱的总油量不能走到当前地点float totalDist = 0;//统计走了多少路for (int j = 0; j < gas.size(); j++)totalDist += gas[j].dist;printf("The maximum travel distance = %.2f", totalDist);return 0;}//能够到当前地点for (int j = gasIndex; j < gas.size(); j++){//遍历邮箱里面存在的油,如果价格比当前油站要高,那么就更新价格//实际的意义相当于:到了当前的站还有油剩(这些油可加可不加),且之前加的油价格比当前油站要高(这些油没必要在之前加),那么在之前就不加油了,全换成到这个站才加油if (gas[j].price>sta[now].price)gas[j].price = sta[now].price;}//把油补充满gas.push_back(gasNode(sta[now].price, cMax - totalGas));totalGas = cMax;}//计算总价格float totalCost = 0;for (int i = 0; i < gas.size(); i++){totalCost += gas[i].cost;}printf("%.2f", totalCost);return 0;}


0 0