pat 1033 To Fill or Not to Fill(值得重点回顾)

16 篇文章 0 订阅
8 篇文章 0 订阅

有点难度的贪心题,贪心策略有点绕,得静下心来分析,同时得增强自己的代码能力。实质是汽车加油问题。

贪心策略:假设现在自己处于A站,要考虑的是A站要不要加油,加多少油的问题。找到下一个要加油的站B(距离A站cmax*davg范围内的最便宜的站)。

1. A站油价比B价高,现在油箱里还有油,能跑到B站,那就不加油,直接跑去(这里B站跟2,3情况不同,是距离A站currGas*davg范围内的最便宜的站)

2. A站油价比B价高,现在油箱没油,跑不到B站,为了减少花销,尽量少加油,只加能跑到B站的油。

3. A站油价比B价低,则不管油箱有没有油,跑不跑得到B站,尽量加满油。

 

AC代码:

//1033 20:23
#include<cstdio>
#include<cstdlib>
const int NUM=505;
const int INF=0x7fffffff;
struct station
{
    double price;
    double dist;
}s[NUM];


int cmp(const void *a,const void *b)
{
    station *x=(station *)a;
    station *y=(station *)b;
    return x->dist - y->dist;
}
int main()
{
    int i,j,n,davg;
    int flag=1,index;
    double dest,cmax;
    //freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);

    scanf("%lf%lf%d%d",&cmax,&dest,&davg,&n);
    for(i=0;i<n;i++){
        scanf("%lf%lf",&s[i].price,&s[i].dist);
    }
    s[n].price=0;
    s[n].dist=dest;
    double step=cmax*davg;

    double currGas=0;

    double minPrice,sum=0;
    qsort(s,n,sizeof(s[0]),cmp);

    if(s[0].dist>0){
        printf("The maximum travel distance = 0.00\n");
        return 0;
    } else {
        for(i=0;i<n;){
            if(s[i+1].dist-s[i].dist>step){
                flag=0;
                printf("The maximum travel distance = %.2lf\n",s[i].dist+step);
                break;
            } else {
                index=i;
                minPrice=s[i].price;
                //1.现在有油,
                for(j=i+1;s[j].dist-s[i].dist<=currGas*davg&&j<=n;j++){//找现有油箱能跑到的比现在最便宜的油站
                    if(s[j].price<minPrice){
                        index=j;
                        minPrice=s[j].price;
                    }

                }
                if(index!=i){//现在有油,找到了比现在油站价格最便宜的油站(不加油能到),就直接开过去,不加油,到那再加
                    currGas-=(s[index].dist-s[i].dist)/davg;//耗油
                    i=index;
                    continue;
                }


                index=i;
                //minPrice=s[i].price;
                //2.现在没油或所能到的油站价格都比现在油站贵
                for(j=i+1;s[j].dist-s[i].dist<=step&&j<=n;j++){//找最近的比现油站便宜的油站
                    if(s[j].price<minPrice){
                        index=j;
                        break;
                    }
                }
                if(index!=i){//现在没油或现油箱所能到的油站价格都比现在油站贵:要去最近的比现油站便宜的油站(不加油到不了),得在现油站加上刚好满足的油量
                    sum+=((s[index].dist-s[i].dist)/davg-currGas)*s[i].price;
                    currGas=0;
                    //printf("%.2lf\n",sum);
                    i=index;
                    continue;
                }

                //3.现在有油或没油,没找到比现在便宜的油站,当然是在现油站加满,再到下一个次便宜的油站

                index=i;
                minPrice=INF;
                for(j=i+1;s[j].dist-s[i].dist<=step&&j<=n;j++){//找接下来step范围内的最便宜油站
                    if(s[j].price<minPrice){
                        index=j;
                        minPrice=s[j].price;
                    }
                }
                sum+=(cmax-currGas)*s[i].price;//没找到比现在便宜的油站,当然是在现油站加满,再到下一个次便宜的油站
                currGas=cmax-(s[index].dist-s[i].dist)/davg;
                //printf("%.2lf\n",sum);
                i=index;

            }
        }
    }
    if(flag==1)
        printf("%.2lf\n",sum);


    return 0;

}


 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值