1. 程式人生 > >藍橋杯 算法訓練 ALGO-15 旅行家的預算

藍橋杯 算法訓練 ALGO-15 旅行家的預算

n) strong ron 駕駛 def 出發點 con 時間限制 開始

算法訓練 旅行家的預算 時間限制: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\n"); 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\n", total); 83 84 return 0; 85 }

藍橋杯 算法訓練 ALGO-15 旅行家的預算