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;
}
}