PAT A1033 贪心

PAT A1033 贪心

注意:

结构体中的变量和普通的变量一样都是要用&进行scanf的,当然类似于字符数组,无论是不是结构体中的元素都是不需要加&进行scanf的。

double 的格式话输入方式是%lf ,类似于float应该用%f进行输入。

1 在当前车站可以达到的所有车站中,选择一个油价最低的车站,然后加到那个车站的油。但是如果当前车站到不了下一个车站(终点也被视为一个车站),就加满,然后GG;目标是多加低价的油。

2 判断两个车站之间的距离是不是加满油也过不去;
3 判断可以到达的车站的油价和自己当前车站的油价,如果高,就尽可能在本站多加油;如果少,就加到足够到哪里去的油(同样适用于最后车站,因为最后车站是0元)

贪心的本意就是每次都选择最大的结果。

这题,包括PAT的很多编程的题目给我的感觉是不要一口气想吃个胖子,你比如说,这个题最简单的形式就是能不能到,然后的形式就是花多少钱到,然后就是怎么样花最少的钱到。即使是最后的问题,我们也不应该上来就在程序中设置一大堆的各种参数,然后维护起来头疼无比。我们应该做的就是一步一步来。DIJ算法也是同理。

门外汉感觉这个题有点自动机的感觉。

#include<iostream> 
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 510;
const int inf = 0x3fffffff;

int n;
double cmax,D,Davg;
struct node{
	double d;
	double p;
}Node[maxn];

bool cmp(node a,node b){
	if(a.d != b.d)  return a.d < b.d;
}

int main(){
	scanf("%lf %lf %lf %d",&cmax,&D,&Davg,&n);
	Node[0].d = D;
	Node[0].p = 0.0;
	
	for(int i=1 ;i<=n;i++){
		scanf("%lf %lf",&Node[i].p,&Node[i].d);
	}
	sort(Node,Node+n+1,cmp);
	//现在距离杭州的距离 

	
	//满油作战半径 
	double dav = cmax * Davg;
	//当前车站 
	int cur_sta = 0;
	//经济 
	double cur_fuel = 0.0;
	double bill = 0.0;
	
	while(cur_sta != n) {
		//不存在可以到达的下一站 
		if((Node[cur_sta+1].d - Node[cur_sta].d) > dav){
			printf("The maximum travel distance = %0.2lf",Node[cur_sta].d + dav);
			return 0; 
		}
		//存在可以到达的下一站 
		else{
			double min_price = inf;
			//这种情况就是默认设置为cur_sta +1,否则,如果你一直找不到低价的车站会一直被困在这里 ,也就是洗循环
			//考虑到后面的车站都贵的要死,所以这里单纯是寻找后面的便宜车站 
			int next_sta = cur_sta+1;
			for(int i=cur_sta + 1;i <= n && (Node[i].d - Node[cur_sta].d <= dav) ;i++) {
				if(Node[i].p < min_price){
					//别忘了更新油价 
					min_price = Node[i].p; 
					next_sta = i;
				}
			}
			//知道了可以到达的最cheap的车站的index 
			
			//一种错误的做法如图所示,因为你可能后面的价格更贵啊!!! 
//			double fuel_need = (Node[next_sta].d - Node[cur_sta].d)/Davg;
//			if(fuel_need > cur_fuel){
//				double add_fuel = fuel_need - cur_fuel;
//				bill += Node[cur_sta].p * add_fuel;
//			}
			
			
			//不是考虑该不该加油,而是考虑到底是这个地方加油还是下一个地方加油
			if( Node[cur_sta].p >= Node[next_sta].p ) {
				double fuel_need = (Node[next_sta].d - Node[cur_sta].d)/Davg;
				if(cur_fuel >= fuel_need){
					
				}
				//油不够 
				else{
					double add_fuel = fuel_need - cur_fuel; 
					cur_fuel = fuel_need;
					bill += add_fuel*Node[cur_sta].p;
				}
			}
			//当前车站更便宜 
			else{
				double add_fuel = cmax - cur_fuel;
				cur_fuel += add_fuel;
				bill += add_fuel*Node[cur_sta].p;
			} 			
			cur_fuel -= (Node[next_sta].d - Node[cur_sta].d)/Davg;
			cur_sta = next_sta;
		}
	}
	printf("%0.2lf",bill);
	return 0;
}

一种错误的思路就是:

	//满油作战半径 
	double dav = cmax * Davg;
	//当前车站 
	int cur_sta = 0;
	//经济 
	double cur_fuel = 0.0;
	double bill = 0.0;
	while(cur_sta != n) {
		//不存在可以到达的下一站 
		if((Node[cur_sta+1].d - Node[cur_sta].d) > dav){
			printf("The maximum travel distance = %0.2lf",Node[cur_sta].d + dav);
			return 0; 
		}
		//存在可以到达的下一站 
		else{
			double min_price = inf;
			//这种情况就是默认设置为cur_sta +1,否则,如果你一直找不到低价的车站会一直被困在这里 ,也就是洗循环
			int next_sta = cur_sta+1;
			for(int i=cur_sta + 1;i <= n && (Node[i].d - Node[cur_sta].d <= dav) ;i++) {
				if(Node[i].p < Node[cur_sta].p){
					//别忘了更新油价 
					min_price = Node[i].p; 
					next_sta = i;
				}
				//应该已经获取了下一个车站的位置 
			}
			cur_sta = next_sta;
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值