pat 甲级 1033 To Fill or Not to Fill

贪心算法
贪心的思想不难,难在怎么分析出来一条最全面的方法

都在代码里了

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

struct sta{

    double price;
    double dis;
    sta(double _p, double _d) : price(_p), dis(_d) {}
};

bool cmp(sta a, sta b){
    return a.dis < b.dis;
}

vector<sta> station;
double maxtank, distan;
int  per, n;
int cur;

int main(){

    scanf("%lf%lf%d%d",&maxtank,&distan,&per,&n);
    for(int i=0; i<n; i++){
        double a, b;
        scanf("%lf%lf",&a,&b);
        station.push_back(sta(a,b));
    }

    sort(station.begin(),station.end(),cmp);

    if(station[0].dis > 0){  //一开始就没有加油站可以到达 
        printf("The maximum travel distance = 0.00\n");
        return 0;
    }

    double maxcom = maxtank * per;
    double sumprice;
    double now = 0; //当前邮箱油量 
    int dest = -1; //
    int hasstation = 0; // 有没有可以到达的站 
    double stationprice; //当前站的价格
    double stationdis; // 当前站到原点的距离 
    int l = station.size();

    while(cur < l){

        stationprice = station[cur].price;
        stationdis = station[cur].dis;
        dest = -1;
        hasstation = 0;

        for(int i = cur+1; i<l ;i++){
            if( (station[i].dis - stationdis) <= maxcom){
                hasstation = 1; //有能到达的站 
                if(station[i].price < stationprice ){ //找有没有比当前站便宜的 
                    dest = i;                   
                    break;
                }

            }
            else break; //breaks是因为这是拍过序的距离了
                        //如果前面的都到不了后面的更到不了,节约运算时间 
        }// 第一个for循环 找有没有到达站的

        if(hasstation != 1){
            if((distan - stationdis) <= maxcom){ //没有下一站但是可以直接到终点 
                double need = distan - stationdis;
                if(now*per >= need) break;
                else {
                    double last = need - now * per;
                    sumprice += (last/per) * stationprice;
                    break;                  
                }
            }
            else { //没有下一站而且到不了终点 
                double maxdis = stationdis +  maxtank * per;
                printf("The maximum travel distance = %.2lf\n",maxdis);
                return 0;
            }
        }
        else {
            if(dest != -1){ //有下一站而且更便宜
                double need = station[dest].dis - stationdis;
                if(need <= now*per){ //油够 
                    now -= need/per; //去掉消耗的油 
                }
                else { //油不够,加满,只记钱数就行,油用完就是 0 
                    sumprice += (need - now*per)/per*stationprice;
                    now = 0;
                } 
                cur = dest; //更新站点 
            }
            else { //有下一站但是没有现在的便宜 

                if((distan - stationdis) <= maxcom){ //能到终点就直接去 
                    double need = distan - stationdis;
                    if(now*per < need)
                    sumprice += (need - now*per)/per*stationprice;
                    break;
                }

                int minprice = 9999999;
                int mincur = -1;
                for(int i=cur+1; i<l; i++){
                    if((station[i].dis - stationdis) <= maxcom ){
                        if(station[i].price < minprice){
                            minprice = station[i].price;
                            mincur = i;
                        } 

                    }
                    else break;
                }
                cur = mincur;
                sumprice += (maxtank - now)*stationprice;
                now = maxtank - (station[cur].dis - stationdis)/per;

            } 
        }

    }//while 循环结束 
    printf("%.2lf",sumprice);

    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值