• 算法训练 旅行家的预算


    https://www.cnblogs.com/cao-lei/p/7243599.html(原博客)转载(写的很棒)

    题目::

    算法训练 旅行家的预算  

    时间限制:1.0s   内存限制:256.0MB
    问题描述
      一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,……N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
    输入格式
      第一行为4个实数D1、C、D2、P与一个非负整数N;
      接下来N行,每行两个实数Di、Pi。
    输出格式
      如果可以到达目的地,输出一个实数(四舍五入至小数点后两位),表示最小费用;否则输出“No Solution”(不含引号)。
    样例输入
    275.6 11.9 27.4 2.8 2
    102.0 2.9
    220.0 2.2
    样例输出
    26.95
     
    题目解析:

      将起点想象成第 0 个加油站,终点想象成 N+1 个加油站
        第 0 个加油站距离起点的距离为 0,第 N+1 加油站距离起点的距离为 D1
        第 0 个加油站的价格为 P,第 N+1 加油站的价格为 0
        根据油箱容量 C 和每升汽油能能行驶的距离 D2 可以计算出油箱加满油可以行驶的最大距离 maxDis

      无解:(在输入时就判断,尽快找出无解情况)
        如果两个加油站的距离大于加满油可以行驶的最大距离,那么无解


      有解:
        从当前位置的下一个加油站寻找距离最近且便宜的加油站:
          1. 如果能找到了
            (1)如果能一次加油到达,那么加到刚好能到达便宜的加油站即可
            (2)如果一次不能到达,那么先将油箱加满,到达行驶最大距离之前的那个加油站,再加到刚好行驶到的便宜那个加油站
          2. 如果没找到,则加满油,行驶到最大距离之前的那个加油站,继续寻找
        注意:终点的加油站价格为 0,所以最后一次加油加到刚好到达终点即可

     1 #include<iostream> 
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 #define MAX_NUM  1001
     6 
     7 int main()
     8 {
     9     int N;
    10     double D1, C, D2, P;
    11     scanf("%lf%lf%lf%lf%d", &D1, &C, &D2, &P, &N);
    12 
    13 //    double * distance = new double[N+5];    //加油站i到起点的距离
    14 //    double * price = new double[N+5];          //油的价格 
    15     double  distance[MAX_NUM];
    16     double  price[MAX_NUM];
    17 
    18     distance[0] = 0;            //记录第i个点离出发点的距离 
    19     price[0] = P;                //起点的油价 
    20     distance[N+1] = D1;            //终点为最后一个加油站 
    21     price[N+1] = 0;                //终点价格 
    22 
    23     double total = 0;            //费用 
    24     double surplus=0;            //到第i个加油站的时候的剩余油量 
    25     double maxDis = C * D2;        //加满油行使的最大距离 
    26     bool flag = true;            //是否有解,默认有解 
    27     
    28     for (int i = 1;i <= N; i++)
    29     {
    30         scanf("%lf%lf", &distance[i], &price[i]);
    31         if (distance[i] - distance[i-1] > maxDis)    //如果两个加油站的距离大于加满油可以行使的距离 ,则无解 
    32         {
    33             flag = false;    //无解 
    34         } 
    35     }
    36     
    37     if(!flag)    //无解 
    38     {
    39         printf("No Solution
    ");
    40         return 0;    
    41     }
    42 
    43     /*
    44         i:当前加油站的编号
    45         j:下一个比自己便宜的加油站的编号 
    46     */ 
    47     for (int i = 0, j; i <= N; i = j)    //到达j之后,将j赋值给i,重新循环,知道到达终点 
    48     {
    49         for (j = i + 1; j <= N + 1; j++)    //从i的下一个开始找比它便宜的加油站 
    50         {    
    51             if (distance[j] - distance[i] > maxDis)    //如果不能行使到比它便宜的加油站 
    52             {
    53                 j--;                        //则先行驶到便加满油后能驶得最大距离之前的加油站 
    54                 break;
    55             }
    56             if (price[j] <= price[i])        //找比现在所在的加油站便宜的加油站 
    57             {
    58                 break;
    59             } 
    60         }
    61 
    62         /*
    63             从当前位置的下一个加油站寻找距离最近且便宜的加油站:
    64             1 如果能找到了
    65                 (1)如果能一次加油到达,那么加到刚好能到达便宜的加油站即可
    66                  (2)如果一次不能到达,那么先将油箱加满,到达行驶最大距离之前的那个加油站,再加到刚好行驶到的便宜那个加油站
    67             2 如果没找到,则加满油,行驶到最大距离之前的那个加油站,继续寻找
    68         */
    69         
    70         if (price[j] <= price[i])    //属于(1)
    71         {
    72             total += ((distance[j] - distance[i]) / D2 - surplus) * price[i];    //加到可以刚好行使到 j 点 
    73             surplus = 0;                                    //剩余油量 
    74         }
    75         else    //属于(2)或 2 
    76         {
    77             total += (C - surplus) * price[i];                //油箱加满 
    78             surplus = C - (distance[j] - distance[i]) / D2;    //到j点时剩余油量 
    79         }
    80     }
    81     
    82     printf("%.2lf
    ", total);
    83         
    84     return 0;
    85 }

    虽然是照抄,但关键你要理解!!!!!!!!

    纵使单枪匹马,也要勇闯天涯
  • 相关阅读:
    Valid Palindrome
    Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode: LRU Cache
    LeetCode: Max Points on a Line
    LeetCode: Evaluate Reverse Polish Notation
    LeetCode:Two Sum
    LeetCode: Binary Tree Postorder Traversal
    LeetCode:Binary Tree Maximum Path Sum
    iOS开发 入门学习总结(二)Objective-C 语法特性总结
    LeetCode: Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/sj-gank/p/11423204.html
Copyright © 2020-2023  润新知