洛谷P1016(旅行家的预算)

洛谷P1016(旅行家的预算)

题目描述

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格PP和沿途油站数N(N可以为零),油站ii离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入格式

第一行,D1,C,D2,P,N
接下来有N行。
第i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。

输出格式

所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

解题思路

  这一题,有点麻烦,本来想用滚动数组的,就像P1004那样,但是有个问题,里面涉及到汽车油量的问题,如果前面的油没用完,那么会影响到后面的花费问题,也就是说,它们并不是一个相互独立的问题,而是相互关联的。
  但是我们可以结合实际去考虑这一题,现实生活中,我们如果进行长途旅行,如果两个加油站之间的距离,就算我们用完汽车油箱里所有油都到不了,那就只能输出"No Solution"了,表示我们无能为力啊,实在到不了。然后就算我们到得了,也要考虑花费问题,毕竟省下来的钱我们可以用来买好多好吃的。这里我们可以知道C*D2是我们的能到达范围。如果在能到达的范围内有一个加油站比现在所处的加油站油价便宜,那么只要刚刚好到那个加油站就好了,因为后续的路我们可以用更加便宜的油行驶下去,如果不巧,我们能到达的范围油价都比我们现在所处的加油站的油价贵,那么加满,并且选择那些贵的加油站中的最便宜的加油站作为下一次加油点。一次一次行驶下去,最后到了终点城市,这时候,油箱里应该没有剩下油了,才能说明我们花的钱用的刚刚好。
  因为我是自学这些题的,所以不懂实际怎么判断正确性,但是注意,这道题里有个测试点的答案在0.01位置上是0,我第一次输出没有输出这个0,结果就WA了,还是太年轻了。
  Talking is cheap,show you my code.

代码

#include<iostream>
#include <iomanip>
using namespace std;
double d1;
double c;
double d2;
double p;
int n;
double pi[8];
double di[8];
double cost;
int main() {
	cin >> d1 >> c >> d2 >> p >> n;
	double h = 0;//汽车油量
	for (int i = 1;i <= n;i++) {
		cin >> di[i] >> pi[i];
	}
	pi[0] = p;
	di[n + 1] = d1;
	for (int i = (n+1) ;i > 0;i--) {
		di[i] -= di[i - 1];
		if (di[i] > (c * d2)) {
			cout << "No Solution" << endl;
			return 0;
		}
	}
	int flag = 0;//汽车到的位置
	while (flag != (n + 1)) {
		int i = flag + 1;
		double len = 0;
		double minp = 500;
		int pmin = i;
		while ((len+di[i]) <= (c*d2)) {
			len += di[i];
			if (pi[i] < minp) {
				minp = pi[i];
				pmin = i;
				if (pi[i] <= pi[flag]) {
					break;
				}
			}
			i++;
		}
		if (minp <= pi[flag]) {
			cost += ((len / d2) - h)*pi[flag];
			h = 0;
		}
		else {
			cost += (c - h)*pi[flag];
			h = c - len / d2;
		}
		flag = pmin;
	}
	cout << setprecision(2) << fixed << cost << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值