1033 To Fill or Not to Fill (24分)

最后一个测试点没过  只有24分

1.距离从大到小排序   2.价格从大到小排序

在 从当前站点开始最大所能到达范围里 找到第一个比当前价低的  即到达该站点(油箱必定空),最大距离即为第一个低价站点,花费则是   最大距离与之前所能到达最大距离 之间的耗油量(即处理了油箱非空的情况)

  若没有,则找到所能找到的最低价,在当前站点加满油,然后计算所能到达最大距离(用于与下一站点之间油费的计算)(即处理了油箱非空的情况)

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 500+5;
float C, D, Da;
int n;
float rest = 0;

struct Node {
	float p;
	float dis;
} s[N];

int cmp(Node a, Node b) {
	if(a.dis == b.dis) {
		return a.p < b.p;
	}
	return a.dis < b.dis;
}

int main() {

	cin >> C >> D >> Da >> n;
	int R = C*Da;//加满后能跑的距离

	for(int i=0; i < n; i++) {
		cin >> s[i].p >> s[i].dis;
	}
	sort(s, s+n, cmp);
	/*	for(int i=0; i < n; i++) {
			cout <<  s[i].p << " " <<  s[i].dis << endl;;
		}
	*/	if(s[0].dis) {
		printf("The maximum travel distance = 0.00");
		return 0;
	}
	int  pi=-1, ni=0, nxt=0, mnxt=0;//钱 距离 , 此时的站点
	float d=0, m=0;
	for(int i=0; i<=n; i=ni+1) {
		//cout << pi << ":" << ni << "="<< mnxt << endl;
		nxt = ni;
		mnxt = i;
		while(i <n && s[i].dis <= s[ni].dis+R) {
			if(s[i].p < s[nxt].p) {
				nxt = i;
				break;
			} else {//如果没有  需要找该范围内价格最低的
				if(s[i].p < s[mnxt].p) {
					mnxt = i;
				}
			}
			//	cout << "可选" << i << s[i].p << ":"<< nxt << s[nxt].p << ":"<< mnxt << s[mnxt].p<< "l"<<  ni << endl;
			i++;
		}

		pi = ni;
		//cout << nxt << "《"<< ni << "<"<< mnxt << endl;
		//	cout <<d << endl;

		if(nxt == ni) {
			if(i != mnxt) {//加满
				ni = mnxt;
				m += (C-rest)*s[pi].p;
				d += (C-rest)*Da;
				rest = C-(s[ni].dis-s[pi].dis)/Da;//下一站可能价格更高
//				cout << "加满啊啊啊啊啊啊" << s[pi].p << " "  << d << "???" << ni << ": " << mnxt<< endl;
				if(pi == n-1) break;
			}
		} else {//有比现在价格小的  只需到达该站点即可
			//		cout << nxt << "=====" << ni << " ";
			ni = nxt;
			 need =  (s[ni].dis-d)/Da;
			
			m +=  need* s[pi].p;
			d = s[ni].dis;
			rest = 0;
//			cout <<s[ni].p<< "仅仅到某一站点" << s[pi].p<< " "  << d << endl ;
		}

		if(n-1 == pi || pi == ni) { //加满都没有加油站了
			/*	m += min(D-d, C*Da)/Da * s[pi].p;
				d = min(D, d+C*Da);*/
			ni = mnxt;
			m += (C-rest)*s[pi].p;
			d += (C-rest)*Da;
//			cout << "找不到加油站了" << s[pi].p<< " "  << d << endl;
			break;
		}

		if(d >= D) {
//			cout << "开心结束!!!!" << endl;
			m -= (d-D)/Da*s[pi].p;
			d = D;
			break;
		}
	}

	if(d >= D) {
		m -= (d-D)/Da*s[pi].p;
		d = D;
	}
	if(d == D) {
		printf("%.2f\n", m);
	} else 		printf("The maximum travel distance = %.2f\n", d);
	return 0;
}

/*
50 1300 12 7
6.00 1300
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
6.85 300
*/

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值