PAT (Advanced Level) 1033 To Fill or Not to Fill (模拟)

 贪心加模拟。

先分两种情况:

       1.从这个点加满油可以到达终点

             a.从剩下的路程中找是否有价格更便宜的,如果有,就先到那个点(这里注意是一旦找到便宜的就立马结束本次寻找,先过去早说)。

             b. 如果没有更便宜的,就直接到终点。

       2.无法从这点到达终点

             a.同上一种的a

             b.判断下,是否这点能到的最大距离内是否有别的点,如果有则选一个价格最低的作为后继点;如果没有,则表明这次已经无法到达终点了,那么加满油,到达最大距离就结束整个模拟。

其中还需要注意的是汽油的存量,大部分时候,并不需要用到汽油的存量,因为如果能找到更便宜的后继点,我们并不需要加满油,只需要能到达后继点即可,因此这段路程中实际上相当于存量未变。但如果是要加满的情况下啊,就要先计算原来有多少,再进行下一步计算。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring> 
#include<climits>
using namespace std;

int c, final_dis, avg, n, max_cover;
struct Station{
	float price, dis;
	bool operator < (const Station &a) const {
		return dis < a.dis;
	}
}stations[505];
int main(){
	scanf("%d%d%d%d",&c,&final_dis,&avg,&n);
	max_cover = c * avg;
	for(int i = 0; i < n; ++i){
		scanf("%f %f",&stations[i].price,&stations[i].dis);
	}
	sort(stations,stations+n);
	if(stations[0].dis != 0) {
		printf("The maximum travel distance = 0.00");
		return 0;
	}
	float cost = 0, pos = 0, tmp_price = stations[0].price, cap = 0;
	int index = 0;
	while(pos < final_dis){
		float min_price = tmp_price;
		int next_index = index;
		if(pos + max_cover >= final_dis){//can arrive
			for(int i = index; i < n; ++i){//find min price
				if(stations[i].price < min_price){
					min_price = stations[i].price;
					next_index = i;
					break;
				}
			}
			if(min_price < tmp_price){//min price exist
				cost += ((stations[next_index].dis - stations[index].dis)/avg-cap)*stations[index].price;
				pos = stations[next_index].dis;
				index = next_index;
				tmp_price = min_price;
			}
			else{
				cost += (final_dis - stations[index].dis)/avg*stations[index].price;
				pos = final_dis;
			}	
		}
		else{//can not arrive
			for(int i = index+1; i < n; ++i){//find min price

				if(pos + max_cover < stations[i].dis) break;
				
				if(stations[i].price <= min_price){
					min_price = stations[i].price;
					next_index = i;
					break;
				}
			}
			if(min_price <= tmp_price && index != next_index){//find a less price next
				cost += (stations[next_index].dis - stations[index].dis)/avg*stations[index].price;
				tmp_price = stations[next_index].price;
				pos = stations[next_index].dis;
				index = next_index;
			}
			else{ 
				min_price = INT_MAX;
				for(int i = index+1; i < n; ++i){//find min price
					if(pos + max_cover < stations[i].dis) break;
					if(stations[i].price < min_price){
						min_price = stations[i].price;
						next_index = i;
					}
				}
				if(next_index == index){
					pos += max_cover;
					break;
				}
				else{
					cost += (c*1.0-cap)*stations[index].price;
					cap = c*1.0 - (stations[next_index].dis - stations[index].dis)/avg;
					pos = stations[next_index].dis;
					index = next_index;
				}
			}
		}
	}
	if(pos == final_dis){
		printf("%.2f",cost);
	}
	else
		printf("The maximum travel distance = %.2f",pos);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值