zoukankan      html  css  js  c++  java
  • [Luogu] P1016 旅行家的预算

    题目描述

    一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

    输入输出格式

    输入格式:

    第一行,D1CD2PN

    接下来有N行。

    i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。

    输出格式:

    所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

    题目解析

    看好多人用队列做的,然而并不想用

    可以这样想,每次遇到加油站就把油箱里的“贵油”卖掉,再把油箱加满地沟油。得出的结果是一样的。

    为了方便判断油的价格,rk[x]表示第x个油站的价格排名,bag[x]表示排名为x的油在油箱里有多少,注意细节模拟就可以了

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 10;
    
    struct Station {
        int id;
        double price;
        friend bool operator < (Station x,Station y) {
            return x.price < y.price;
        }
    } s[MAXN];
    
    struct Oil {
        double sum;
        double price;
        double rk;
    };
    
    int n;
    double cub,ech,ans;//分别是油箱容量,每升油跑多远,共多少钱
    double p[MAXN],dis[MAXN],bag[MAXN];//价格 离起点的距离 油箱
    int rk[MAXN];
    
    int main() {
        double tmp;
        scanf("%lf%lf%lf%lf%d",&tmp,&cub,&ech,&p[1],&n);
        dis[n+2] = tmp;
        s[1].id = 1;
        s[1].price = p[1];
        n++;
        for(int i = 2;i <= n;i++) {
            scanf("%lf%lf",&dis[i],&p[i]);
            s[i].price = p[i];
            s[i].id = i;
            p[i] = s[i].price;
            if(dis[i]-dis[i-1] > cub*ech) {
                printf("No Solution
    ");
                return 0;
            }
        }
        sort(s+1,s+1+n);
        for(int i = 1;i <= n;i++) {
            rk[s[i].id] = i;
        }
    //    for(int i = 1;i <= n;i++) {
    //        cout<<i<<" "<<p[i]<<" "<<dis[i]<<" "<<rk[i]<<endl;
    //    }
        for(int i = 1;i <= n+1;i++) {
            double tot = 0;
            double need = (dis[i]-dis[i-1]) / ech;
            for(int j = 1;j <= n;j++) {
                if(need >= bag[j]) need -= bag[j],bag[j] = 0;
                else if(need) {
                    bag[j] -= need;need=0;
                    break;
                }
            }
            if(i == n+1) break;
            for(int j = 1;j <= n;j++) {
                if(!bag[rk[j]]) continue;
                if(rk[i] < rk[j]) {
                    ans -= bag[rk[j]] * (p[j]-p[i]);
                    bag[rk[i]] += bag[rk[j]];
                    bag[rk[j]] = 0;
                }
                tot += bag[rk[j]];
            }
            bag[rk[i]] += cub - tot;
            ans += (cub-tot) * p[i];
    //        for(int j = 1;j <= n;j++) printf("%.2lf ",bag[j]);
    //        cout<<" with ans is: "<<ans<<endl;
        }
        for(int i = 1;i <= n;i++) ans -= bag[rk[i]] * p[i];
        printf("%.2lf
    ",ans);
        return 0;
    }
  • 相关阅读:
    C#中的global::system***命名空间别名限定符
    返回一个整数数组中最大子数组的和
    敏捷开发概述
    单词查找排序输出
    关于电梯调度的设计
    关于电梯调度的一些想法
    C#中抽象类和接口的区别
    SharePoint2010列表表单:用后台代码生成表单
    外刊IT评论:远离.net
    程序员:编程给你现实生活带来了哪些坏习惯
  • 原文地址:https://www.cnblogs.com/floatiy/p/9674890.html
Copyright © 2011-2022 走看看