九度oj 1437 贪心


我的思路是对于每个加油站,计算出在此加油站所能加的最大的油量所能覆盖最大的距离中没单位距离所需要的价钱,若两个加油站覆盖的距离有交集,那么这个交集部分选价钱小的那个,另一个退出这个交集。

同时,我们需要注意精度

const double eps=1e-8

fabs(a-b)<eps  等价于a==b

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#define ISYEAP(x) x%100!=0 && x%4==0 || x%400==0 ? 1:0
using namespace std;
long long int arr[610];
const double eps=1e-8;
double Cmax;//油箱体积
double Dis;//起始与终点的距离
double Davg;//一升油能跑的距离
int N;//加油站的个数
struct oilStation{
   double price;
   double distanceToHangzhou;
};
struct ratio{
  double start;
  double end;
  double priceRatio;
  bool weatherIsWork;
}rat[510];
void input(){
   oilStation temp;
   for(int i=0;i<N;i++){
     scanf("%lf%lf",&temp.price,&temp.distanceToHangzhou);
     rat[i].start=temp.distanceToHangzhou;
     rat[i].end=rat[i].start+Cmax*Davg;
     rat[i].priceRatio=temp.price/Davg;
     rat[i].weatherIsWork=true;
   }
}
bool cmp(ratio a,ratio b){
  if(a.start==b.start){
    return a.priceRatio<b.priceRatio;
  }
  return a.start<b.start;
}
void findSolution(){
   for(int i=0;i<N-1;i++){
     for(int j=i+1;j<N;j++){
            if(rat[i].weatherIsWork==false)
              continue;
            if(rat[i].end-rat[j].start<eps){
              break;
            }
            if(fabs(rat[i].start-rat[j].start)<eps && fabs(rat[i].end-rat[j].end)<eps){
               if(rat[i].priceRatio-rat[j].priceRatio<eps )
                  rat[j].weatherIsWork=false;
                else{
                  rat[i].weatherIsWork=false;
                }
                continue;
            }
            if((rat[i].start-rat[j].start)>=eps&& (rat[i].end-rat[j].end)<=eps){
                 rat[i].weatherIsWork=false;
                 break;
            }
            if(rat[i].end-rat[j].start>eps){
                if( rat[i].priceRatio-rat[j].priceRatio<eps){
                   rat[j].start=rat[i].end;
                }
                else{
                   rat[i].end=rat[j].start;
                }
            }


      }
   }
   float start=0;
   float end=0;
   float NeedMoney=0;
   for(int i=0;i<N;i++){
       if(end==Dis)
         break;
     if(rat[i].weatherIsWork==false || rat[i].start==rat[i].end)
       continue;
     if(start==end && rat[i].start!=0){
       break;
     }
     else{
        if(end==rat[i].start){
          if(rat[i].end>=Dis)
            {
                rat[i].end=Dis;
            }
          NeedMoney+=rat[i].priceRatio*(rat[i].end-rat[i].start);
          end=rat[i].end;
        }
     }
   }
   int abs=(int)(NeedMoney*100);
   if(NeedMoney*100-abs>=0.5)
   {
       abs=abs+1;
   }
   if(end<Dis){
       printf("The maximum travel distance = %.2lf\n",end-start);
   }
   else{
      printf("%.2lf\n",(double)abs/100);
   }
}
int main(){
  while(scanf("%lf%lf%lf%d",&Cmax,&Dis,&Davg,&N)!=EOF){
     input();
     sort(rat,rat+N,cmp);
     findSolution();
  }
}




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值