本文主要是介绍储油点问题 C语言/C++语言 最详细版,附含第0点储油量大家的值不同的解释,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题:
一辆重型卡车欲穿过1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500升。显然,卡车装一次油是过不了沙漠的。因此,司机必须设法在沿途建立几个储油点,使卡车能够顺利穿越沙漠。试问:司机如何建立这些储油点?每一储油点应储存多少油,才能使卡车以消耗最少汽油的代价通过沙漠?
算法分析:
编程计算及打印建立储油点的序号,各储油点距离沙漠边缘的出发距离以及储油量。
题目有点难理解,我来解释一下吧。
先看最终要的结果:(这个不是正确的,往下看)
题目啥意思呢,其实就是问要怎样才能通过沙漠,卡车装满油最多只能500公里,剩下的500公里没有油跑了,怎么办呢,储存油呗,然后就是题目真正问题了,就是该怎么储存所需要的油具体的说:
设储油点编号为:0,1,……i, i+1,……n,(n为最后一个)由题目的意思可知,最后一个储油点n应该是在距离终点500公里的地方(因为剩下的这500公里刚好是可以一车油跑完的嘛),那么现在的问题就是该怎么在倒数第二储(即:n-1)油点 储存满500升油呢,而且还要保证车开到n-1这点时,把剩余油全部储存进去后刚好500升(可以理解为装满500升油的同时车又是刚好耗空了所有油。)
!!!!!!!!!!!!!!!!逆向思维!!!!!!!!!!!!!!!!!!!!
提示一下:车是不可能直接一次就把500升油存满的,跑到那个点去的路途上是要耗油的吧,存了一部分油还得留一部分返回去拉第二趟的油吧。
就是说在n-1这个点时车要把油分成三份(500/3的三等份),花500的三分之一去往n这个点,然后存500的三分之一进去,再花剩余的三分之一回到n-1这个点,然后第二趟又是装500升满的去往n这个点,路途还是花掉500的三分之一,剩余2/3,全部存进n点去,n点刚好500升,自己也刚好没有油了,再把500升全拿出去装车,刚好能跑完剩下的500公里。 ……以此类推……
分析一下:
用oil(i)表示第 i 个点的储油量,dis(i)表示第 i 点到终点的距离(0<i<n);
(注意,这不是题目求的到出发点距离,1000-dis[i] 才是)。
最后一个点 n :距离dis[n]=500;油 oil(n)=500;
倒数第二个点 n-1:距离dis[n-1]=dis[n]+500/3; 油oil[n-1]=2*500 ( 拉了两趟嘛,每趟500 )
继续推下去可知n-2: 距离dis[n-2]=dis[n-1]+500/5;油oil[n-2]=3*500
………………
是不是可以发现规律了。
倒过来算储油点,把最后一个算第 1 个点,倒数第二个算第 2 个点,……第一个算最后一个 n点;
那么规律不就是这样嘛:
第 i 点 : 距离:dis[i]=dis[i-1]+(2*n-1);
油:oil[i] =i*500;
这下就会了吧。
献上代码(若对13、14行不理解,看后面解释):
#include<iostream>
using namespace std;
int main(){int i=0,k=1;float dis[10],oil[10];dis[0]=oil[0]=0;dis[1]=oil[1]=500;while(dis[k]<=1000){k++;dis[k]=dis[k-1]+500/(2*k-1);oil[k]=k*500;}dis[k]=1000;oil[k]=(1000-dis[k-1])*(2*k-1)+oil[k-1];cout<<"NO. distance(k.m) oil(l.)"<<endl;for(k;k>=0;k--)cout<<i++<<" "<<1000-dis[k]<<" "<<oil[k]<<endl; return 0;
}
因为总长只有1000公里,代码里第k个点(额……也就是题目求的第一点)应该是距离终点1000公里,距离起点0公里才对,而如果没有这两句(可以注释这两句后运行看一下,结果会是下面这样子),求出来的点表示的已经是距离终点1008公里,起点 -8公里的点了,明显不对,所以只能单独求解;
距离好求,就是1000公里。
储油量呢,应该是上一个点所需要的油量 oil[k-1] 加上往返(2*k-1次)跑的路程(1000-dis[k-1)所需要消耗的油量对吧,这个很好理解吧
所以oil[k]=(1000-dis[k-1])*(2*k-1)+oil[k-1];
C语言:
#include<stdio.h>
int main(){int i=0,k=1;float dis[10],oil[10];dis[0]=oil[0]=0.0;dis[1]=oil[1]=500.0;while(dis[k]<=1000){k++;dis[k]=dis[k-1]+500.0/(2*k-1);oil[k]=k*500.0;}dis[k]=1000.0;oil[k]=(1000.0-dis[k-1])*(2*k-1)+oil[k-1];printf("NO. distance(k.m) oil(l.)\n");for(k;k>=0;k--)printf("%d %.2f %.2f\n",i++,1000.0-dis[k],oil[k]);return 0;
}
改成浮点型了
特别提醒:
关于第0个储油点的油量,我看到了很多的答案,发现大家的有些出入,于是我特意验算了一下:
由第1 个点22.43公里可以算出:
起点到第 1 个点距离22.43公里,要往第 1 个点存 3500升油。
第一趟:去耗22.43升,存455.14升,留22.43升回起点
第二趟:……… , 存了910.28升,…………
第三趟:……… , 存了1365.42升,…………
第四趟:……… , 存了1820.56升,…………
第五趟:……… , 存了2275.70升,…………
第六趟:……… , 存了2730.84升,…………
第七趟:……… , 存了3185.98升,…………
第八趟:耗22.43升,加这次够3500升了,无需返回了,全存,有3663.54升(装500升多了)
多了 3663.55-3500=136.55升,应该减掉
实际应该装 500-136.55=336.45 升
也就是前七趟都是拉500升(7*500)去第 1 点,而第八趟拉336.45升去第 1点就可以了,所以出发点需要7*500+336.45=3836.45升油(因为电脑计算有精度丢失,所以小数存在了0.05的误差)
综上所诉:3836.XX这个值才是正确的,切记。
这篇关于储油点问题 C语言/C++语言 最详细版,附含第0点储油量大家的值不同的解释的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!