A1033 To Fill or Not to Fill [贪心]

在这里插入图片描述
题目大意:先给油箱容量,再给距离目的地距离和每升油能跑的公里数,给一条直线上的加油站的距离和每升费用,如果能跑到输出最少烧油的钱,如果跑不到最大跑的输出距离。

题目思路:

  1. 先根据每个加油站的距离从小到大排序,然后循环扫描比当前加油站更低的单价且能到达就记住加油站位置。如果没有更低就扫描一个其中单价最低的出来。如果一个都到不了直接跳出循环了可以。
  2. 扫描到更低的就直接跳出循环,先加油到刚好能去单价更低的加油站加油,以这个加油站为起点,再搜寻是否有更低的加油站。
  3. 如果没有更低就扫描一个其中单价最低的出来。然后加满油到这里去,再扫描。
  4. 将重点可以记做一个费用为0距离为目的地的加油站,结束标志是到了这个加油站。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
struct station
{
	double price;
	double dis;
}st[510];
bool cmp(station a, station b)
{
	return a.dis < b.dis;
}
int main()
{
	int n;
	double maxoil, D, disavg;
	cin >> maxoil >> D >> disavg >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> st[i].price >> st[i].dis;
	}
	st[n].price = 0;
	st[n].dis = D;
	sort(st, st + n, cmp);
	if (st[0].dis != 0)
	{
		cout << "The maximum travel distance = 0.00" << endl;
	}
	else
	{
		int now = 0;
		double allcost = 0, nowoil = 0,  maxdis = maxoil * disavg;
		while (now < n)
		{
			int k = -1;
			double pricemin = 1000000000;
			for (int i = now + 1; i <=n&& st[i].dis - st[now].dis <= maxdis; i++)
			{
				if (st[i].price < pricemin)
				{
					pricemin = st[i].price;
					k = i;
					if (pricemin < st[now].price)
					{
						break;
					}
				}
			}
			if (k == -1)         //根本无法到达一个加油站,直接输出结果
				break;
			double needoil = (st[k].dis - st[now].dis) / disavg;
			if (pricemin < st[now].price)
			{
				if (nowoil < needoil)
				{
					allcost += (needoil - nowoil) * st[now].price;
					nowoil = 0;
				}
				else
				{
					nowoil -= needoil;
				}
			}
			else
			{
				allcost += (maxoil - nowoil) * st[now].price;
				nowoil = maxoil - needoil;
			}
			now = k;
		}
		if (now == n)
		{
			printf("%.2f\n", allcost);
		}
		else
		{
			printf("The maximum travel distance = %.2f", st[now].dis + maxdis);
		}
	}
}
posted @ 2020-07-09 21:43  _Hsiung  阅读(61)  评论(0编辑  收藏  举报