PAT (Advanced Level) Practice 1033 To Fill or Not to Fill (25 分)(贪心)

很坑的一道贪心题

策略是:
如果范围内有离他最近比它便宜的,就只加油到能够达到那个点的量。

如果没有,就加满,然后到它范围内最便宜的点。

注意:有很多特判

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
const ll inf=0x3f3f3f3f;
#define read(x) scanf("%lld",&x)


struct node
{
    double pric;
    double dis;
    bool operator < (const node& x)const
    {
        return dis<x.dis;
    }
}a[1005];
int main()
{
    double C,D,avg;
    cin>>C>>D>>avg;
    ll N;
    cin>>N;
    for(int i=0;i<N;i++)
    {
        scanf("%lf %lf",&a[i].pric,&a[i].dis);

    }
    sort(a,a+N);


    double lef=0.0;

    ll pos=0;
    double maxlen=C*avg;
    double ans=0;
    if (a[0].dis!=0)
    {
        double tt=0;
        cout << "The maximum travel distance = ";
        printf("%.2lf\n",tt);
        return 0;
    }
    while (true) {
        double pp=0;
        ll nxtpos = -1;
        for (int i = pos + 1; (i < N) && (a[i].dis - a[pos].dis <= maxlen); i++) {
            if (a[i].pric <= a[pos].pric)//!!!!!!!!!!!
            {
                nxtpos = i;
                break;
            }
        }
        if (nxtpos == -1) {
            if (a[pos].dis + maxlen >= D) {
                double needgas = (D - a[pos].dis) / avg;

                if (lef >= needgas) {
                    printf("%.2lf\n",ans);
//                    cout << ans << '\n';
                    return 0;
                } else {
                    printf("%.2lf\n",ans + (needgas - lef) * a[pos].pric);
//                    cout << ans + (needgas - lef) * a[pos].pric;
                    return 0;
                }
            }

            double minnprc = 10000000.0;
            for (int i = pos + 1; (i < N) && (a[i].dis - a[pos].dis <= maxlen); i++) {
                if (a[i].pric < minnprc) {
                    minnprc = a[i].pric;
                    nxtpos = i;
                }
            }

            if (nxtpos == -1) {
                cout << "The maximum travel distance = ";
                printf("%.2lf\n",a[pos].dis + maxlen);
                return 0;
            }

            ans += (C - lef) * a[pos].pric;
            pp+=(C - lef) * a[pos].pric;
            lef = C;

            lef-=(a[nxtpos].dis-a[pos].dis)/avg;

        } else {
            double needgas = (a[nxtpos].dis - a[pos].dis) / avg;
//            if (pos==6)cout<<needgas<<"!"<<'\n';
            if (lef >= needgas) {
                lef = lef - needgas;
            } else {

                ans += (needgas - lef) * a[pos].pric;
//                if (pos==6)cout<<(needgas - lef)<<"!\n";
                pp+=(needgas - lef) * a[pos].pric;
                lef = 0;
            }
        }

//        cout<<pos<<' '<<nxtpos<<' '<<a[nxtpos].dis-a[pos].dis<<' '<<pp<<' '<<lef<<'\n';
        pos = nxtpos;


    }

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shihao Weng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值