求一个算法问题.(C#) 一个骆驮运玉米从A地到B地, 骆驮一次最多运1000个玉米,A地距离B地有1000米远.而骆驮每走1米就要吃一个玉米.现在有3000个玉米.现在要从A运到B.问到B地最多还能剩下多少个玉米???? 求算法过程. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你再说一下你的题呢,你是不是想要在运到B地的时候玉米的数量最多,而不是每次必须走到B地后再返回,如果你每次必须走到B地再回到A地,那玉米明显的不够骆驼吃啊 先是分段运.......然后再来个if(粮食<=1000){ 给老子直接往前冲!!}else{ 继续分段运,分段你可以写个递归.} 就是求最大值啊,我做出的答案是533(不知道对不对.有没有大侠做出更多的.).但是我不知道应该怎么用语言(比如C#,VB,C,C++)写出来.我学过C#,但是我没有学过数据结构与算法.请教个位大侠了. ACM竞赛性质的题目。期待这方面的高手。 ACM International Collegiate ProgrammingContest.ACM国际大学生程序设计竞赛 偏重于算法设计的一个竞赛。国内许多好的大学也在搞。有不少大学提供了OJ系统,可以答题并且系统自动回复。如http://acm.pku.edu.cn/JudgeOnline/。 比如下面这个题目和你的问题有点类似:穿越沙漠一辆吉普车来到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)。 输出每个测试例对应一行输出,包含一个数,表示最少的油耗量。 输入样例25001000输出样例500.0003836.497 这个问题正好做过,嘿嘿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); } }} 我最喜欢这样的思考题了,这种有趣的问题,比电子游戏还要吸引我。===============================需要分段。每次运输量是固定的,并且分段越长,消耗越大,所以每次走最短分段路程就能达到最省效果。当然,分段越短,走的次数越多,但此题并不考虑路程繁杂平衡问题。当分段为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 Systemlet maxLoad = 1000let total = 3000let unitDeplete = 1let totalRoad = 1000let getLoad quantity = Math.Min(quantity, maxLoad)let getDepletion x = x * unitDepletelet 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 !targetlet 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)) roadListlet quantityList = List.map (fun i -> finalLoad(i)) roadListlet quantity = List.max quantityListprintfn "当单位路程为%A时,运到目的地量最多,为%A。" road quantityignore(Console.ReadKey())事后对比一下,发现对这个问题来讲,F#除了程序短些外,没有表现出特别精彩的地方。估计是这个题太简单,没有高阶函数的用武之地。当然,也有部分原因是我的F#水平不到家,使不出它的精髓来。 程序的话用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哦,调和级数的问题第一次走到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...... xuexi!! return target > 0 ? target : 0; 是什么意思啊?? return target > 0 ? target : 0;相当于:if(target>0) return target;else return 0; C# winform程序 实现定时自动从远程linux服务器FTP下载文件 Stream的Close问题??? C#创建一个简单聊天室怎么做啊? C#对AutoCad二次开发的问题 asp.net 2.0下的编译问题 已知对方用户名和密码如何拷贝走上面的文件 这样做有必要吗? 关于用API创建椭圆窗体的问题,达人请进。 怎样让DataSet只填充数据架构,而不填充数据。 ERP VS 家庭主妇 visual studio.net 2003 修复安装后,会不会将补丁破坏 将xml文档中的数据读到Dataset里面之后再用GridView显示出来
if(粮食<=1000)
{
给老子直接往前冲!!
}
else
{
继续分段运,分段你可以写个递归.
}
(2)吉普车在沙漠边沿A点到终点B的直线距离为x≧500公里(即沙漠宽度);
输入
输入的第一行含一个正整数k (1<=k<=6),表示测试例的个数。后面紧接着k行,每行对应一个测试例,包含一个正整数x,表示从A点到B点的距离(1<=x<=2000)。
输出每个测试例对应一行输出,包含一个数,表示最少的油耗量。 输入样例
2
500
1000输出样例
500.000
3836.497
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);
}
}
}
===============================
需要分段。每次运输量是固定的,并且分段越长,消耗越大,所以每次走最短分段路程就能达到最省效果。
当然,分段越短,走的次数越多,但此题并不考虑路程繁杂平衡问题。
当分段为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 Systemlet 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#水平不到家,使不出它的精髓来。
程序的话用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
哦,调和级数的问题第一次走到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...... xuexi!!
return target > 0 ? target : 0; 是什么意思啊??
相当于:
if(target>0)
return target;
else
return 0;