【蓝桥杯】 算法训练 旅行家的预算

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

个人思路:【贪心】

  • 1)首先考虑如果加满油都不能到达下一个加油站,则肯定无法到达目的地,则输出" N o No No S o l u t i o n Solution Solution"
  • 2)既然是贪心,那么费用得最少。
  • 寻找下一个比当前加油站便宜的加油站,如果能找到比当前加油站便宜的加油站,且一次加油即可到达,则把油加到刚好能到达该加油站即可,否则把油加到最满,行驶到最大距离之前的加油站,然后再加油到该便宜的加油站;如果不能到达,则把油加满,行驶到最大距离之前的加油站
#include <iostream>
#include <cstdio>
using namespace std;
double D1, C, D2, P, N;
double Dis[1005];  //记录加油站的距离 
double Price[1005];  //记录加油站的价格 
double maxdis, total, remain;  //分别表示从起点加满油所能到达的最远距离、总费用、剩余油量 
int main() {
	int N;
	cin >> D1 >> C >> D2 >> P >> N;
	Dis[0] = 0;  //标记起点为第一个加油站 
	Price[0] = P;
	Dis[N + 1] = D1;  //标记终点为最后一个加油站 
	Price[N + 1] = 0;
	maxdis = C * D2;  //标记最远达到的距离 
	bool flag = true;
	for (int i = 1; i <= N; ++i) {
		cin >> Dis[i] >> Price[i];
		//判断下一个加油站是否可达,如不可达则无解 
		if (Dis[i] - Dis[i - 1] > maxdis)
			flag = false;
	}
	if (!flag) {
		cout << "No Solution!" << endl;
		return 0;
	}
	/*
	*  i:当前加油站的编号 
	*  j:下一个比当前便宜的加油站 
	*/ 
	for (int i = 0, j; i <= N; i = j) //到达j之后,令j为当前加油站,重新循环 
	{  
		for (j = i + 1; j <= N + 1; j++)//从当前加油站i的下一个开始寻找比i便宜的加油站 
		{ 
 			if (Dis[j] - Dis[i] > maxdis) //如果不能行驶到比它便宜的加油站 
			{ 
 				j--;                    //则先行驶到加满油能行驶到的最大距离之前的加油站,即i->j之间的加油站 
 				break;
			}
			if (Price[j] <= Price[i]) {  //找比当前加油站便宜的加油站 
				break;
			}
 		}
 		/*
 		 *  从当前位置的下一个加油站寻找距离近且便宜的加油站 
		 *	1. 如果能找到 
		 *    (1)  如果能一次加油到达便宜的加油站,那么把油加到刚好能到达这个便宜的加油站即可 
		 *    (2)  如果不能一次到达,那么把油加满,到达行驶最大距离之前的加油站,再加油到这个便宜的加油站 
		 *  2. 如果不能找到,则加满油,到达行驶最大距离之前的加油站 
		 * 	    
		 */ 
 		
 		if (Price[j] <= Price[i]) {  //找到比当前便宜的加油站 
 			total += ((Dis[j] - Dis[i]) / D2 - remain) * Price[i]; //加到刚好能到达j即可 
 			remain = 0;
		}
		else { //不能一次到达或不能找到 
			total += (C - remain) * Price[i];  //把油加满 
			remain = C - (Dis[j] - Dis[i]) / D2;  //剩余油量 
		}
	}
	printf("%.2lf\n", total);
	return 0;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值