题目1437:To Fill or Not to Fill
利用贪心法,每次走一站,记录当前距离,当前油箱油量。
贪心策略:
在当前站向前看,如果一次可行驶最大距离内有较便宜的加油站,加油量到可以行驶到第一个最便宜的站点
如果最大距离以内当前站最便宜,加满油
如果任意一站到下一站的距离超过最大距离,则无法到达
特殊情况:初始站点没有加油站
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
class Station
{
public:
int dis;
float pri;
Station()
{
dis = 0;
pri = 0;
}
};
bool cmp(Station a, Station b)
{
return a.dis < b.dis;
}
Station s[501];
float res;//结果
int main()
{
int cmax, d, n, i, j;
float davg;
int maxDis;//加满一次行驶最大距离
float res = 0;
while(cin >> cmax)
{
res = 0;
cin >> d >> davg >> n;
maxDis = cmax * davg;
for (i=0; i<n; i++)
{
cin >> s[i].pri >> s[i].dis;
}
s[n].dis = d;//去特殊化
sort(s, s+n, cmp);
if (s[0].dis != 0)
{
cout << "The maximum travel distance = 0.00" << endl;
continue;
}
int curPos=0;
float curOil=0;//当前距离、油箱剩油
for (i=0; i<n ; i++)//每次一站
{
curPos = s[i].dis;
//无法到达终点
if (curPos + maxDis < s[i+1].dis)
{
cout << "The maximum travel distance = ";
cout << setiosflags(ios::fixed) << setprecision(2) << curPos+maxDis +0.0<< endl;
break;
}
//减掉中间行驶耗油
if (i>0)
{
curOil = curOil - (s[i].dis - s[i-1].dis)/davg;
}
//如果最大距离内有较便宜
int curDis = 0;
bool isCheap = false;
for (j=i+1; j<n; j++)
{
curDis = s[j].dis - s[i].dis;
if (curDis>maxDis)//如果没有
{
//res += (cmax - curOil)*s[i].pri;
//curOil = cmax;
break;
}
if (s[j].pri<s[i].pri)//有行驶到便宜站
{
float temp = curOil;
curOil = (s[j].dis - s[i].dis )/davg;//应保证油量
if (temp - curOil < 0)
{
res += (curOil - temp)*s[i].pri;//补充加油
}
else
{
curOil = temp;//不需要加油
}
isCheap = true;
break;
}
}// end of for
//最大距离内未找到便宜站
if (!isCheap)
{
if (curPos+maxDis>=d)//到达终点
{
res += ((d - curPos)/davg - curOil) *s[i].pri;
cout << setiosflags(ios::fixed) << setprecision(2);
cout << res << endl;
break;
}
else//未到终点,加满油
{
res += (cmax - curOil)*s[i].pri;
curOil = cmax;
}
}
}//end of for (每次一站)
}//end of while
return 0;
}