PAT A1033 To Fill or Not to Fill 常规思路和实现

题目链接
《算法笔记》上面的思路非常实用,但实现过程不够直观,书上的参考代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=510;
const int INF=100000;
struct Station{
	double price, dis;
}st[maxn];
bool cmp(Station a, Station b){
	return a.dis<b.dis;
}
int main(){
	int n;
	double Cmax, D, Davg;
	scanf("%lf%lf%lf%d",&Cmax, &D, &Davg, &n);
	for (int i=0; i<n; i++){
		scanf("%lf%lf", &st[i].price, &st[i].dis);
	}
	st[n].price=0;
	st[n].dis=D;
	sort(st,st+n, cmp);
	if (st[0].dis){
		printf("The maximum travel distance = 0.00\n");
	}else {
		int now=0;
		double ans=0, nowTank=0, MAX=Cmax*Davg;
		while (now<n){
			int k=-1;
			double priceMin=INF;
			for (int i=now+1; i<=n && st[i].dis-st[now].dis<=MAX; i++){
				if (st[i].price<priceMin){
					priceMin=st[i].price;
					k=i;
					if (priceMin<st[now].price){
						break;
					}
				}
			}
			if (k==-1) break;
			double need=(st[k].dis-st[now].dis)/Davg;
			if (priceMin <st[now].price){
				if (nowTank < need){
					ans+=(need-nowTank)*st[now].price;
					nowTank=0;
				}else {
					nowTank-=need;
				}
			}else {
					ans+=(Cmax-nowTank)*st[now].price;
					nowTank=Cmax-need;
				}
				now=k;
			}
		if (now==n){
			printf("%.2f\n",ans);
		}else {
			printf("The maximum travel distance = %.2f\n",st[now].dis+MAX);
		}
	}
}

像我这种小白,只会用最笨的代码来实现,按照确定的思路,分类讨论,如下:

#include <cstdio>
#include <algorithm>
using namespace std;
struct Sta{
	double price, distance;
}sta[510];
bool cmp(Sta a, Sta b){
	return a.distance<b.distance;
}
int main(){
	double cmax,d,davg;
	int n;
	scanf("%lf%lf%lf%d",&cmax, &d, &davg,&n);
	for (int i=0; i<n; i++){
		scanf("%lf %lf",&sta[i].price, &sta[i].distance);
	}
	sta[n].price=0;
	sta[n].distance=d;
	sort(sta,sta+n+1,cmp);
	if (sta[0].distance){
		printf("The maximum travel distance = 0.00");
		return 0;
	}else {
		double maxDis=davg*cmax;
		int now=0;
		double distance=0, payment=0, nowTank=0;
		int flag=1;
		while(now<n){
			distance=sta[now].distance+maxDis;
			if (distance<sta[now+1].distance) {
				printf("The maximum travel distance = %.2f",distance);
				return 0;
			}else {
				flag=1;
				for (int i=now+1; sta[i].distance<=distance && i<=n; i++){
					if (sta[i].price<sta[now].price){
						double dis=sta[i].distance-sta[now].distance;
						double needGas=dis/davg;
						if (nowTank>=needGas){
							nowTank-=needGas;
						}else {
							payment+=(needGas-nowTank)*sta[now].price;
							nowTank=0;
						}
						now=i;
						flag=0;
						break;
					}
				}
				if (flag){
					int min=now+1;
					for (int i=now+2; sta[i].distance<=distance && i<=n; i++){
						if (sta[min].price>sta[i].price) {
							min=i;
						}
					}
					double dis=sta[min].distance-sta[now].distance;
					double needGas=dis/davg;
					payment+=(cmax-nowTank)*sta[now].price;
					nowTank=cmax-needGas;
					now=min;
				}
			}
		}
		printf("%.2f",payment);
	}
}

代码长了一点点,但是条理更清楚,小白也只能写出这样的了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值