【PAT】A1033

分析已经写在代码中 真不容易啊 又变菜了

/** This is Code of JJ

Problem      :
Source       :
Solution     :
AnyDetial    :

DateAndTime  :
CostofTime   :
分析
设置A当前站点,B最大距离内站点,C最大距离外站点
1)当前站点无剩余油
    1 最大距离内 有比当前站点价格低的站点B
        立即前往最近的站点B并要走多少加多少,因为多加油会浪费在B点
    2 最大距离内 只有比当前站点价格高或等于的站点B
        找价格最低的站点, 并加满油 因为到了B之后的油价比A点的高,
            而且B之后的油价价格而亏钱 因为找不到比A更低的站点了
2)有剩余燃油
    与1)类似

Tip 添加一个虚拟加油点
        可节省大量工作
**/

#include<iostream>
#include<cmath>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct Node
{
    double dis;
    double price;
} sta[520];

int cmp(Node a,Node b)
{
    return a.dis!=b.dis?a.dis<b.dis:a.price<b.price;
}
double cap,dis,pcap, left_gas;
int n;
int main()
{
    scanf("%lf%lf%lf%d",&cap,&dis,&pcap,&n);
    for(int i=0; i<n; i++)
    {
        scanf("%lf%lf",&sta[i].price,&sta[i].dis);
    }
    sta[n]= {dis,0};//!在终点加一个加油站 妙啊 若可以到达 必定可以找到一个包括终点加油站的序列
    n++;
    sort(sta,sta+n,cmp);
    double amount = 0;
    if(sta[0].dis)
    {
        printf("The maximum travel distance = 0.00\n");
        return 0;
    }
    for(int i=0; i<n;)
    {
        if(sta[i].dis>=dis) break;//!若改为判断i==n-1时结束,则会报错,因为多个终点相同的加油点
        int  minprice = 0x3fffffff;
        int minidx = i,have = 0;//!flag = 1 没有价格小于当前站点i价格的站点
        for(int j=i+1; sta[j].dis-sta[i].dis<=cap*pcap; j++)
        {

            if(minprice > sta[j].price)//!尽量近一点
            {
                have = 1;
                minidx = j;
                minprice = sta[j].price;
                if(minprice < sta[i].price) break;//!找到比当前小的就要去哪里
            }
        }
        if(have)
        {
            double need = (sta[minidx].dis - sta[i].dis)/pcap;
            if(minprice >= sta[i].price)//
            {
                amount += (cap-left_gas) * sta[i].price;
                left_gas = cap -  need;//!拉满油箱
            }
            else
            {
                if(left_gas>need)
                {
                    left_gas -= need;
                }
                else
                {
                    //!顺序颠倒
                    amount += (need-left_gas)*sta[i].price;
                    left_gas = 0;
                }
            }
            i = minidx;///!忘了
        }
        else
        {
            printf("The maximum travel distance = %.2lf\n",sta[i].dis + cap*pcap);
            return 0;
        }
    }
    printf("%.2lf\n",amount);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值