求一个算法问题.(C#)

pengliang1982 2010-07-10 08:50:14
一个骆驮运玉米从A地到B地, 骆驮一次最多运1000个玉米,A地距离B地有1000米远.

而骆驮每走1米就要吃一个玉米.现在有3000个玉米.现在要从A运到B.

问到B地最多还能剩下多少个玉米????


求算法过程.
...全文
621 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
QIHONGWEI_2000_0 2010-08-11
  • 打赏
  • 举报
回复
36楼的思路是对的
zlRun 2010-07-12
  • 打赏
  • 举报
回复
学习了···
mill_dhl 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 xdbjzhhh 的回复:]
引用 57 楼 xdbjzhhh 的回复:

一个卡车就拉过去完了。。。。。。。
拖拉机也行。。。。。。
[/Quote]
其实手推车也可以的
yanglinqiang 2010-07-11
  • 打赏
  • 举报
回复
路过!
「已注销」 2010-07-11
  • 打赏
  • 举报
回复
[Quote=引用 57 楼 xdbjzhhh 的回复:]

一个卡车就拉过去完了。。。。。。。
[/Quote]拖拉机也行。。。。。。
「已注销」 2010-07-11
  • 打赏
  • 举报
回复
一个卡车就拉过去完了。。。。。。。
rcy5211314 2010-07-11
  • 打赏
  • 举报
回复
看回帖看晕了
woebird 2010-07-10
  • 打赏
  • 举报
回复
学习中..........
chas824045706 2010-07-10
  • 打赏
  • 举报
回复
呵呵,看看
color2002 2010-07-10
  • 打赏
  • 举报
回复
1000m的距离也不是很远,何不让骆驼一次性吃饱,比如50个(应该能饱吧),然后让它跑三趟把所有玉米运完呢
wantalcs 2010-07-10
  • 打赏
  • 举报
回复
我最喜欢这样的思考题了,这种有趣的问题,比电子游戏还要吸引我。
===============================
需要分段。每次运输量是固定的,并且分段越长,消耗越大,所以每次走最短分段路程就能达到最省效果。
当然,分段越短,走的次数越多,但此题并不考虑路程繁杂平衡问题。
当分段为1米时,最终运到目的地的玉米最多,为533个。
===============================
计算代码:

class Program
{
private static readonly int _maxLoad = 1000; //单次运载上限
private static readonly int _totals = 3000; //需要被运载总量
private static readonly int _unitDeplete = 1; //运输单位距离消耗食品量
private static readonly int _road = 1000; //全路长度

/// <summary>
/// 求本次实际运载量
/// </summary>
/// <param name="quantity">本次剩余需要运载的量</param>
/// <returns>本次实际运载量</returns>
private static int GetLoad(int quantity)
{
return Math.Min(quantity, _maxLoad);
}

/// <summary>
/// 计算运载过程需要消耗的食品量
/// </summary>
/// <param name="x">运载距离</param>
/// <returns>总消耗量</returns>
private static int GetDepletion(int x)
{
return x * _unitDeplete;
}

/// <summary>
/// 单段路程运载结果
/// </summary>
/// <param name="x">运载的路程</param>
/// <param name="quantity">需要被运载的量</param>
/// <returns>最后运到目的地的量</returns>
private static int PartLoad(int x, int quantity)
{
int target = 0; //运到目的地的量
int origin = quantity; //剩余需被运载量

target = GetLoad(origin) - GetDepletion(x);
origin = origin - GetLoad(origin);

while (GetLoad(origin) > GetDepletion(2 * x)) //只要剩余可运量大于来回路程消耗量,就回头去运输
{
target += (GetLoad(origin) - GetDepletion(2 * x));
origin -= (GetLoad(origin));
}

return target;
}

/// <summary>
/// 计算是指定分段路程下,最终运到目的地的量
/// </summary>
/// <param name="x">分段路程长度</param>
/// <returns>最终到达目的地量</returns>
private static int FinalLoad(int x)
{
int road = _road; //剩余路程
int target = _totals; //运到的量

while (road > x) //只要剩余路程大于单位路程,就继续运输
{
road -= x;
target = PartLoad(x, target);
if (target <= 0) //如果把所有食品都消耗完了,运输失败,没意义继续下去了。
{
break;
}
}
if (target > 0)
{
target = PartLoad(road, target); //运输余下最后一段路程
}

return target > 0 ? target : 0;
}

static void Main(string[] args)
{
int unitRoad = 0; //单位路程
int quantity = 0; //最终运量
for (int i = 1; i <= 1000; i++)
{
int target = FinalLoad(i);
if (target > quantity)
{
quantity = target;
unitRoad = i;
}
}
Console.WriteLine(string.Format("当单位路程为{0}时,最后运载量最大,可达到{1}。", unitRoad, quantity));
Console.ReadKey();
}
}

一般说来,对于这样计算型问题,用F#比用C#更合适。
一并列出F#代码

open System

let maxLoad = 1000
let total = 3000
let unitDeplete = 1
let totalRoad = 1000
let getLoad quantity = Math.Min(quantity, maxLoad)
let getDepletion x = x * unitDeplete
let partLoad x quantity =
let target = ref 0
let origin = ref quantity
target := getLoad !origin - getDepletion x
origin := !origin - getLoad !origin
while getLoad !origin > getDepletion 2 * x do
target := !target + (getLoad !origin - getDepletion 2 * x )
origin := !origin - getLoad !origin
!target
let finalLoad x =
let road = ref totalRoad
let target = ref total
while !road > x && !target > 0 do
road := !road - x
target := partLoad x !target
if !target > 0 then target := partLoad !road !target
Math.Max(!target , 0)

let roadList = [1..1000]
let road = List.maxBy (fun i -> finalLoad(i)) roadList
let quantityList = List.map (fun i -> finalLoad(i)) roadList
let quantity = List.max quantityList
printfn "当单位路程为%A时,运到目的地量最多,为%A。" road quantity
ignore(Console.ReadKey())

事后对比一下,发现对这个问题来讲,F#除了程序短些外,没有表现出特别精彩的地方。估计是这个题太简单,没有高阶函数的用武之地。当然,也有部分原因是我的F#水平不到家,使不出它的精髓来。
pengliang1982 2010-07-10
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 litaoye 的回复:]
哦,不好意思,剩下的应该是8/15,1000 * 8/15 = 533.333......

程序的话用3000/1000,就是说可以循环2次,然后用(1/5 + 1/3) * 1000就可以了

如果是5000的话,就是(1/9 + 1/7 + 1/5 + 1/3) * 1000

如果是5438的话,稍微复杂一些(1/9 + 1/7 + 1/5 + 1/3) * 1000 + 43……
[/Quote]

可以给个代码看看吗(C#)?
salrookie11544 2010-07-10
  • 打赏
  • 举报
回复
路过!
supercpu123 2010-07-10
  • 打赏
  • 举报
回复
这题早几年不是驴吗,这几年都进化成骆驼了啊
绿色夹克衫 2010-07-10
  • 打赏
  • 举报
回复
哦,不好意思,剩下的应该是8/15,1000 * 8/15 = 533.333......

程序的话用3000/1000,就是说可以循环2次,然后用(1/5 + 1/3) * 1000就可以了

如果是5000的话,就是(1/9 + 1/7 + 1/5 + 1/3) * 1000

如果是5438的话,稍微复杂一些(1/9 + 1/7 + 1/5 + 1/3) * 1000 + 438/11

[Quote=引用 32 楼 pengliang1982 的回复:]

引用 29 楼 litaoye 的回复:
哦,调和级数的问题

第一次走到1/5处,放下3/5,回头
第二次走到1/5处,拿上1/5,走到1/5 + 1/3处,放下1/3,回头,走到1/5,拿上1/5
第三次,走到1/5处拿上1/5,走到1/5 + 1/3处,拿上1/3,然后一直走到头,可以剩1-1/5-1/3 = 7/15
所以可以剩1000 * 7/15 = 466.6666..……
[/Quote]
yaj52125 2010-07-10
  • 打赏
  • 举报
回复
关注中……
pengliang1982 2010-07-10
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 litaoye 的回复:]
哦,调和级数的问题

第一次走到1/5处,放下3/5,回头
第二次走到1/5处,拿上1/5,走到1/5 + 1/3处,放下1/3,回头,走到1/5,拿上1/5
第三次,走到1/5处拿上1/5,走到1/5 + 1/3处,拿上1/3,然后一直走到头,可以剩1-1/5-1/3 = 7/15
所以可以剩1000 * 7/15 = 466.6666......
[/Quote]

我就是这么想的,我说的533就是这么得来的.1000-467=533.
467是最后一次所走的路程.
我现在需要的是怎么写代码????
绿色夹克衫 2010-07-10
  • 打赏
  • 举报
回复
这个问题正好做过,嘿嘿


using System;
using System.Collections.Generic;

namespace acmtimusru
{
class Program
{
static void Main(string[] args)
{
double[] timesTable = new double[4000];
timesTable[0] = 1;

for (int i = 1; i < timesTable.Length; i++)
timesTable[i] = timesTable[i - 1] + 1.0 / (double)(i * 2 + 1);

string[] inputString = Console.ReadLine().Split(' ');
int total = int.Parse(inputString[0]);
int perTime = int.Parse(inputString[1]);
int indexNum = Array.BinarySearch(timesTable, (double)total / perTime);

if (indexNum < 0)
indexNum = -indexNum - 1;

int spend = (int)((timesTable[indexNum] * perTime - total) * (indexNum * 2 + 1));
Console.WriteLine(perTime * (indexNum + 1) - spend);
}
}
}


[Quote=引用 30 楼 swimmingfish2004 的回复:]

(1)假设吉普车在沙……
[/Quote]
swimmingfish2004 2010-07-10
  • 打赏
  • 举报
回复
比如下面这个题目和你的问题有点类似:

穿越沙漠一辆吉普车来到x公里宽的沙漠边沿A点,吉普车的耗油量为1升/公里,总装油量为500升。通常,吉普车必须用自身油箱中的油在沙漠中设置若干个临时储油点,才能穿越沙漠的。假设在沙漠边沿A点有充足的汽油可供使用,那么吉普车从A点穿过这片沙漠到达终点B,至少要耗多少升油。请编写一个程序,计算最少的耗油量(精确到小数点后3位)。

(1)假设吉普车在沙漠中行进时不发生故障;
(2)吉普车在沙漠边沿A点到终点B的直线距离为x≧500公里(即沙漠宽度);


输入
输入的第一行含一个正整数k (1<=k<=6),表示测试例的个数。后面紧接着k行,每行对应一个测试例,包含一个正整数x,表示从A点到B点的距离(1<=x<=2000)。
输出

每个测试例对应一行输出,包含一个数,表示最少的油耗量。

输入样例
2
500
1000

输出样例
500.000
3836.497
绿色夹克衫 2010-07-10
  • 打赏
  • 举报
回复
哦,调和级数的问题

第一次走到1/5处,放下3/5,回头
第二次走到1/5处,拿上1/5,走到1/5 + 1/3处,放下1/3,回头,走到1/5,拿上1/5
第三次,走到1/5处拿上1/5,走到1/5 + 1/3处,拿上1/3,然后一直走到头,可以剩1-1/5-1/3 = 7/15
所以可以剩1000 * 7/15 = 466.6666......
加载更多回复(40)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧