贪心算法To Fill or not to Fill

To Fill or not to Fill

网址:http://ac.jobdu.com/problem.php?pid=1437

还没有AC,结果不太对,先发出来保存一下,再看看哪里错了。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int Cmax,D,Davg,N;


/*
Cmax:汽车的油桶最大容量(<=100)
D:杭州和目的地的距离(KM)(<=30000)
Davg:平均每单位的汽油可以行走多少公里(<=20)
N:加油站的个数(<=500)*/

//加油站
struct station{
    double up;//汽油单价
    double distance;

    bool operator <(const station &A) const{
          return distance< A.distance;//按照升序排列
    }

}buf[501];

//若下一加油站的价格更便宜,则只需走到下一加油站即可。
//若下一结点的价格没有该节点便宜
//1.若将油箱加满,看看在其能到达的最远距离内,是否有比该点更便宜的站点。
//若有,则正好到达这个跟便宜的点即可;否则,将油箱加满,然后到达这段距离内价格最小的点(除当前点外)。
int main(){
    while(scanf("%d%d%d%d",&Cmax,&D,&Davg,&N)!=EOF){
        int i;
        for(i=0;i<N;i++)
            scanf("%lf%lf",&buf[i].up,&buf[i].distance);
        sort(buf,buf+N);//将加油站按照距离由小到大排序

        double  cost=0.0,X=0.0;
        double currentgas=0.0;
        if(buf[0].distance!=0){
            printf("The maximum travel distance = 0.00\n"); 
            continue;
        }
        i=0;
        while(i<N){
            int j;
            j=i+1;
            /*寻找下一个离它最近的且油价比当前加油站便宜的加油站*/
            while(buf[j].up>=buf[i].up && j<N){
                j++;
            }
            if(j<N){
                /*说明找到了价格更便宜的加油站*/
                /*判断是否可以到达该站*/
                if((currentgas*Davg)<(buf[j].distance-buf[i].distance)){
                    /*说明当前的油不够走到下一个加油站*/
                    /*那么就要在该站加油*/
                    double addgas=(buf[j].distance-buf[i].distance)/Davg-currentgas;
                    cost+=addgas*buf[i].up;
                    X+=buf[j].distance-buf[i].distance;
                    currentgas=0;
                    i=j;
                }
                else{
                    /*说明当前的油够走到下一个加油站*/
                    X+=buf[j].distance-buf[i].distance;
                    double usedgas=(buf[j].distance-buf[i].distance)/Davg;
                    currentgas-=usedgas;
                    i=j;
                }
            }
            else{
                /*说明找不到价格更便宜的加油站*/
                //那么就在该站加满汽油,然后走到允许走到的最远范围内最便宜的加油站

                double addgas=Cmax-currentgas;
                cost+=addgas*buf[i].up;

                //假设第i+1个加油站是最便宜的
                int y=i+1;
                double low=buf[y].up;
                int step=Cmax*Davg; //加满油能行驶的最大距离
                int c; //保存可行范围内最便宜加油站的下标
                while(buf[i].distance+step>=buf[y].distance && y<N){
                    if(buf[y].distance<low){
                        low=buf[y].up;
                        c=y;
                    }   
                    y++;
                }
                if(y<N){
                //当while循环退出时,low和c就是保存了价格最低的加油站 下标及价格。
                    X+=buf[c].distance-buf[i].distance;
                    currentgas=Cmax-(buf[c].distance-buf[i].distance)/Davg;
                    i=c;
                }
                else break;
            }
        }
        if(i=N)
            printf("%.2lf\n",cost);
        else
            printf("The maximum travel distance = %.2lf\n",buf[i].distance+Cmax*Davg); 
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值