算法初步—贪心—A1033

思路:
本题是典型的贪心问题,想要用最少的钱行驶完全程,只需要每次选择最便宜的加油站,加最多的油即可。

1、判断在最大距离范围内下一个站点A是否比当前站点便宜
2、若满足1,则只加刚好到A的油量,重复1
3、若最大距离范围内油价都比当前高,则在当前把油量加满(若可直接到达终点则无需加满)
4、选择剩下站点中最便宜的站点B,重复1

注意点:
1、除了加油站数量外,全都为浮点类型
2、判断不能到达终点有3种情况
a 当前为最后一个站点,且最大行驶距离无法到达目的地
b 最大行驶距离无法到达下一个加油站
c 起始点0处没有加油站

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;

struct Gas_Station //加油站结构体 
{
    double price;  //油价 
    double pos;   //位置 
}s[501];

bool cmp(Gas_Station a,Gas_Station b)
{
    if(a.pos != b.pos)
        return a.pos < b.pos;
    return a.price < b.price;
}

int main()
{
    double C_max,D_avg,D;                              
    double D_cur = 0,D_tank = 0,D_max,sum = 0;
    int N;
    scanf("%lf%lf%lf%d",&C_max,&D,&D_avg,&N);
    D_max = C_max * D_avg;            //计算最大行驶公里数 
    for(int i=0;i<N;i++)
        scanf("%lf%lf",&s[i].price,&s[i].pos);
    sort(s,s+N,cmp);             //将加油站按距离排序 
    int index = 0;
    if(s[0].pos != 0)
    {
        printf("The maximum travel distance = %.2lf",D_cur);
        return 0;
    }
    while(D_cur < D)
    {
        int i = index + 1;
        double up = D_max + D_cur;
        bool flag = false;
        double low_price = s[i].price;
        int low_index = i;

        for(;i<N && s[i].pos <= up;i++)         //如果在最大行驶范围内,有加油站A比当前站油价便宜,则购买刚好能行驶到A的油量 
        {
            if(s[i].price < s[index].price)
            {
                D_cur = s[i].pos;
                if(D_tank < s[i].pos - s[index].pos)    //判断油箱是否有剩余,是否需要加油 
                {
                    sum += s[index].price * (s[i].pos - s[index].pos - D_tank) / D_avg;
                    D_tank = 0;
                }
                else
                    D_tank = D_tank - s[i].pos + s[index].pos;

                index = i;
                flag = true;
                break;
            }
            if(low_price > s[i].price)   //找出最便宜的加油站 
            {
                low_price = s[i].price;
                low_index = i;
            }
        }
        if(!flag) //flag为false说明当前加油站为最便宜 
        {
            if((index == N-1 && up < D) || (up < s[index + 1].pos))
            {
                printf("The maximum travel distance = %.2lf",D_cur + D_max);
                return 0;
            }
            if(up >= D) //可以直接行驶到终点 
            {
                sum += s[index].price * (D - s[index].pos) / D_avg;
                D_cur = D;
            }
            else //不能则在此处加满油,并驶向最大范围内的下一个最便宜加油站 
            {
                sum += s[index].price * (D_max - D_tank) / D_avg;
                D_tank = D_max;
                D_tank -= s[low_index].pos - s[index].pos;
                index = low_index;
                D_cur = s[low_index].pos;
            }
        }
    }
    printf("%.2lf",sum);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值