【题目描述】
题目1437:To Fill or Not to Fill
时间限制: 1 秒 内存限制: 128 兆 特殊判题: 否 提交:3387 解决:771
题目描述:
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年浙江大学计算机及软件工程研究生机试真题
我的思路是,我们可以根据起点(Dsta)和该加油站能达到的最远的终点(Dend=Dsta+Cmax*Davg)来把整个过程划分为若干个阶段。在每个阶段中,我们都有可以选择的汽油价格。我们选择最低价格,乘以距离。加和,最后除以Davg,即得到总的费用(Psum)。因此,我们只需要:
1、确定各个阶段点(Dmid),并降序排序。
2、在各个阶段中确定可选择的价格,排序得到最低价格(acP[0])。
3、将最低汽油价格乘该距离,加和即得到总价格。
根据贪心算法,我们可以证得,只要每个阶段选择的都是最低的,最终价格也是最低的。
以他所给的第一个例子来说:
最终有(7.10*150+7.00*150+6.85*600+7.00*300+7.30*50+6.00*50)/12=749.17(保留两位小数)
当然,还要注意起点没有0和达不到终点的情况。
感觉思路没有什么问题。但一直是WA。代码如下,麻烦大神指正。
#include
#include
using namespace std;
struct GasStation{
double P;
double Dsta;
double Dend;
bool operator < (const GasStation & b) const{
return Dsta<b.Dsta;
}
}G[501];
int main(){
double Cmax,D,Davg;
int n,m,i,j;
double Dmid[1002];
double Psum;
double acP[501];
while(scanf("%lf%lf%lf%d",&Cmax,&D,&Davg,&n)!=EOF){
for(i=0;i scanf("%lf%lf",&G[i].P,&G[i].Dsta);
G[i].Dend=G[i].Dsta+Cmax*Davg;
if(G[i].Dend>D)
G[i].Dend=D;
}
sort(G,G+n);
if(G[0].Dsta!=0){
printf("The maximum travel distance = 0.00\n");
continue;
}
if(G[n-1].Dend printf("The maximum travel distance = %.2lf\n",G[n-1].Dend);
continue;
}
for(i=0;i Dmid[2*i]=G[i].Dsta;
Dmid[2*i+1]=G[i].Dend;
}
sort(Dmid,Dmid+2*n);
Psum=0;
for(i=0;i m=0;
for(j=0;j if(G[j].Dsta=Dmid[i+1])
acP[m++]=G[j].P;
sort(acP,acP+m);
Psum+=acP[0]*(Dmid[i+1]-Dmid[i]);
}
Psum/=Davg;
printf("%.2lf\n",Psum);
}
}
麻烦大神指点,谢谢!
经FancyMouse指正,“到不了还有另一种情况,就是中间没油了,但是头尾都有加油站覆盖。 ”是有这个问题。我修改了青黄不接的问题之后。又加了对于之前的站台,如果不选就抛弃之的修改。总觉得还是有问题,这次也是WA。附代码:
#include
#include
using namespace std;
struct GasStation{
double P;
int Dsta;
int Dend;
bool operator < (const GasStation & b) const{
return Dsta<b.Dsta;
}
}G[501];
int main(){
int Cmax,D,Davg;
int n,m,i,j,k;
int Dmid[1002];
double Psum;
double acP[501];
while(scanf("%d%d%d%d",&Cmax,&D,&Davg,&n)!=EOF){
for(i=0;i scanf("%lf%d",&G[i].P,&G[i].Dsta);
G[i].Dend=G[i].Dsta+Cmax*Davg;
if(G[i].Dend>D)
G[i].Dend=D;
}
sort(G,G+n);
if(G[0].Dsta!=0){
printf("The maximum travel distance = 0.00\n");
continue;
}
//若青黄不接,输出到达的最大距离
for(i=0;i if(G[i+1].Dsta-G[i].Dend>Cmax*Davg){
double tmpD=G[i].Dend;
printf("The maximum travel distance = %.2lf\n",tmpD);
continue;
}
}
if(G[n-1].Dend double tmpD=G[n-1].Dend;
printf("The maximum travel distance = %.2lf\n",tmpD);
continue;
}
for(i=0;i Dmid[2*i]=G[i].Dsta;
Dmid[2*i+1]=G[i].Dend;
}
sort(Dmid,Dmid+2*n);
Psum=0;
k=0;
for(i=0;i m=0;
for(j=k;j if(G[j].Dsta=Dmid[i+1])
acP[m++]=G[j].P;
sort(acP,acP+m);
for(;G[k].P!=acP[0];k++);
//printf("%d-%d:",Dmid[i],Dmid[i+1]);
//for(j=0;j<m;j++)
// printf("%.2lf ",acP[j]);
//printf("\n");
Psum+=acP[0]*(Dmid[i+1]-Dmid[i]);
}
Psum/=Davg;
printf("%.2lf\n",Psum);
}
}