九度oj 1437 To Fill or Not to Fill 2012年浙江大学计算机及软件工程研究生机试真题

题目1437:To Fill or Not to Fill

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:1488

解决:345

题目描述:

With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

输入:

For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=20), the average distance per unit gas that the car can run; and N (<= 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,...N. All the numbers in a line are separated by a space.

输出:

For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print "The maximum travel distance = X" where X is the maximum possible distance the car can run, accurate up to 2 decimal places.

样例输入:
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
50 1300 12 2
7.10 0
7.00 600
样例输出:
749.17
The maximum travel distance = 1200.00
来源:
2012年浙江大学计算机及软件工程研究生机试真题
分析:
 //贪心算法
//dis=满油箱可以开出的最远距离。
//算法描述:起点A开始,到A+dis范围内:
//1.如果存在点B的s[B].price<=s[A].price,只要满足能行驶到B点即可
//2.如果不存在点B的s[B].price<=s[A].price,则要使车能开到 A+dis范围内除A以外,price最小的点--min_index所指点
//注意:
//1.终点如果在 A+dis范围内,一定可达
//2.注意排序后第一个点的dis可能不为0
//3.离A点最近的B点与A的距离如果>dis,则此趟行驶到不了终点
//4.油箱的情况每次都要关注
//具体见代码:
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct station{
double price,dis;
};
station s[];
bool cmp(station a,station b){
return a.dis<b.dis;
}
int main(){
double cmax,d,davg;
int n;
while(scanf("%lf%lf%lf%d",&cmax,&d,&davg,&n)!=EOF){
double min_price=;
double max_dis=;
double cur_tank=;
int i=;
for(;i<n;i++){
cin>>s[i].price>>s[i].dis;
}
s[i].dis=d;
s[i].price=;
sort(s,s+n,cmp);
/*for(i=0;i<=n;i++){
cout<<s[i].dis<<' '<<s[i].price<<endl;
}*/
if(s[].dis>){//2.注意排序后第一个点的dis可能不为0
//cout<<1<<endl;
printf("The maximum travel distance = 0.00\n");
continue;
}
int f=;
double dis=cmax*davg;
int min_index;
while(s[f].dis<d){
int next=f+;
min_index=next;
while((s[next].dis-s[f].dis)<=dis){//如果next==n,一定会从break处出去
//跳出循环只有三种情况:
//1.在dis范围内,没有点与f点的距离小于等于dis
//2.在dis范围内,找到price小于f的点(包括next==n)
//3.next!=n,但在dis范围内,没有找到price小于f的点。在dis范围内,有点与f点的距离小于等于dis
if(s[next].price<s[min_index].price){//记录最小的油价的站点
min_index=next;
}
if(s[next].price<=s[f].price){//在dis范围内,找到price小于f的点
break;
}
next++;
}
if(next==f+&&(s[next].dis-s[f].dis)>dis){//1.在dis范围内,没有点与f点的距离小于等于dis
//cout<<1<<endl;
max_dis+=dis;
break;
}
else{
if((s[next].dis-s[f].dis)<=dis){//2.在dis范围内,找到price小于f的点(包括next==n)
if(s[next].dis-s[f].dis>cur_tank){
min_price+=(s[next].dis-s[f].dis-cur_tank)*s[f].price;
cur_tank=;
max_dis+=s[next].dis-s[f].dis;
}
else{
cur_tank-=s[next].dis-s[f].dis;
max_dis+=s[next].dis-s[f].dis;
}
f=next;
}
else{//3.next!=n,但在dis范围内,没有找到price小于f的点。在dis范围内,有点与f点的距离小于等于dis
min_price+=(dis-cur_tank)*s[f].price;
cur_tank=dis-(s[min_index].dis-s[f].dis);
max_dis+=s[min_index].dis-s[f].dis;
f=min_index;
}
}
}
if(s[f].dis==d){
printf("%.2lf\n",min_price/davg);
}
else{
printf("The maximum travel distance = %.2lf\n",max_dis*1.0);//注意输出格式
}
}
return ;
}
 
上一篇:common-pool2对象池(连接池)的介绍及使用


下一篇:30+WordPress古典风格的主题-古典却不失时尚