PAT (Advanced Level) Practice A1033 To Fill or Not to Fill (25 分)(C++)(甲级)(贪心、贪婪算法、加油站)

版权声明:假装有个原创声明……虽然少许博文不属于完全原创,但也是自己辛辛苦苦总结的,转载请注明出处,感谢! https://blog.csdn.net/m0_37454852/article/details/88354398

原题链接

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <ctime>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
using namespace std;

typedef struct Station
{
    double P, D;
}Station;
typedef struct Car
{
    double price, tank, now_pos, max_pos;
    int s;//处在第几个加油站
}Car;
const int MAX = 510, INF = (1<<30) -1;
vector<Station> S;
Car C = {0};
double Cmax, D, Davg, N;

bool cmp(Station A, Station B)//按加油站距离顺序排序
{
    return A.D < B.D;
}

int main()
{
    scanf("%lf %lf %lf %lf", &Cmax, &D, &Davg, &N);
    for(int i=0; i<N; i++)
    {
        Station A;
        scanf("%lf %lf", &A.P, &A.D);
        S.push_back(A);
    }
    sort(S.begin(), S.end(), cmp);
    if(S[0].D > C.now_pos)
    {
        printf("The maximum travel distance = %.2f\n", C.max_pos);
        return 0;
    }
    while(1)
    {
        C.max_pos = C.now_pos + Cmax*Davg;//在这个加油站加满油最远能到的距离
        double min_price = 99999999;//在这段距离内价格最低的加油站
        int tag = -1;//加油站标号
        for(int i = C.s+1; i < N && S[i].D <= C.max_pos && S[i].D < D; i++)
        {
            if(S[i].P < min_price)
            {
                min_price = S[i].P;
                tag = i;
                if(min_price <= S[C.s].P) break;
            }
        }
        if(tag == -1)//如果找不到,说明到不了下一个加油站
        {
            if(C.max_pos >= D) break;
            printf("The maximum travel distance = %.2f\n", C.max_pos);
            return 0;
        }
        if(S[tag].P > S[C.s].P)//若当前这个加油站比途中那个加油站更便宜
        {
            if(C.max_pos >= D) break;//如果已经能到达终点,就不用在接下来的加油站加油了
            C.price += 1.0*(Cmax - C.tank)*S[C.s].P;//就在这里加满
            C.tank = Cmax - 1.0*(S[tag].D - C.now_pos)/Davg;//计算到途中最便宜加油站的时候剩余油量
        }
        else
        {
            if(C.now_pos+C.tank*Davg <= S[tag].D)
            {
                C.price += 1.0*(S[tag].D-C.now_pos-C.tank*Davg)/Davg*S[C.s].P;//否则就再加需要的那部分油量
                C.tank = 0;//走到那个加油站正好没油
            }
            else C.tank = 1.0*(S[tag].D - C.now_pos)/Davg;
        }
        C.now_pos = S[tag].D;
        C.s = tag;
        //printf("%.2f %.2f\n", C.now_pos, C.price);
    }
    C.price += 1.0*(D-C.now_pos)/Davg*S[C.s].P;//在最后这个加油站加一次油
    printf("%.2f\n", C.price);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37454852/article/details/88354398
今日推荐