PAT甲级 1033. To Fill or Not to Fill (25)

题目:

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.

Input Specification:

Each input file contains one test case. 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.

Output Specification:

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.

Sample Input 1:
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
Sample Output 1:
749.17
Sample Input 2:
50 1300 12 2
7.10 0
7.00 600
Sample Output 2:
The maximum travel distance = 1200.00
思路:

这题做的时候思路没理清,还是看网上的思路整理的。

这大概是贪心算法。

1.首先先将站点按照距离排序,判断第一个站点是否在起点,若不在则无法起步。这个做的时候忘了,测试点通不过时才查出来;

2.判断当前站点是否为最后一个站点:

  1)是最后一个站点:

       判断充满油时能否到终点,若能,则充油恰好到终点,否则,计算能到的最大距离

  2)不是最后一个站点

      找到在该站点充满油能到达的站点,判断是否能到下一个站点:

     2.1)不能到下一个站点:计算能到的最大距离

     2.2)能到下一个站点,判断在能到达站点中是否有比该站点油价便宜的站点:

           a)有:加油至最近的油价比当前站点低的站点

           b)  无:判断是否能直接到终点,能,则加油至终点,不能,则加满油找到能达到站点中最便宜的站点

           由此,达到相应站点后,再进行下一轮判断。


在整理思路的时候,需要考虑到哪个站点加油,加多少油,到达该站点时车里是否还有油,还剩多少油等。


代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct station
{
	float distance;
	float perprice;
	bool operator <(const station & s)const
	{
		return this->distance < s.distance;
	}
};




int main()
{
	//input
	float Cm, D, Davg, N;
	cin >> Cm >> D >> Davg >> N;
	int i,j;
	vector<station> S(N);
	for (i = 0; i < N; ++i)
	{
		cin >> S[i].perprice >> S[i].distance;
	}
	sort(S.begin(),S.end());

	float d = 0.0;
	float p = 0.0;

	float tank = 0.0;
	
	bool flag = 1;
	i = 0;
	float pri_d;

	//判断当前是否能加到油
	if (S[0].distance > 0)
	{
		flag = 0;		
	}

	while (d < D && flag)
	{
		//判断中间是否有加油站
		if (i == (S.size() - 1))
		{
			//没有
			if (Cm*Davg + d >= D)
			{
				//能到达
				p += ((D - d) / Davg - tank)*S[i].perprice;
				d = D;
				tank = 0.0;
			}
			else
			{
				//不能到达
				d += (Cm*Davg);
				flag = 0;
				break;
			}
		}
		else
		{
			//中途还有加油站
			pri_d = Cm*Davg + d;
			for (j = i; j < N; ++j)
			{
				if (pri_d < S[j].distance)
					break;
			}
			if (j == i + 1)
			{
				//说明无法到下一个站点
				d = pri_d;
				flag = 0;
				break;
			}
			else
			{
				//在充满油能达到的站点里找到最便宜的
				int t, tmp;
				tmp = i + 1;
				bool f = 0;
				for (t = i + 1; t < j; ++t)
				{
					if (S[t].perprice < S[i].perprice) //有比当前节点便宜的加油站
					{
						f = 1;
						break;
					}
					if (S[tmp].perprice >= S[t].perprice)//能到达的加油站中最便宜的
						tmp = t;
				}
				if (f)
				{
					//t站点油价低,充一部分油支撑到t站点
					if ((S[t].distance - S[i].distance) / Davg > tank)
					{
						//需要加油
                                             p += ((S[t].distance - S[i].distance) / Davg - tank)*S[i].perprice;
					     tank = 0.0;
					}
					else
					{
						//不需要加油
						tank = tank-(S[t].distance - S[i].distance) / Davg;
					}
					i = t;
					d = S[i].distance;
				}
				else
				{
					//接下来的站点油都比当前站点贵
					if (pri_d >= D)
					{
						//能直接到终点
						p += ((D - d) / Davg - tank)*S[i].perprice;
						d = D;
					}
					else
					{
						//不能直接到终点,加满油到最便宜的站点
						p += (Cm - tank)*S[i].perprice;
						tank = Cm - (S[tmp].distance - S[i].distance) / Davg;
						i = tmp;
						d = S[i].distance;
					}
				}
			}

		}
	}

	//output
	if (flag)
	{
		printf("%.2f\n",p);
	}
	else
	{
		printf("The maximum travel distance = %.2f\n",d);
	}
	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值