C语言经典题目

题目
有N个人想要用一条每次只能坐两人的船过河,因此,需要合理的安排来、回以使所有的人都能顺利过河。每个人过河的速度不同,两个人速度取决于速度较慢的一个。你的任务就是想一个策略让所有的人在最短的时间内均过河。

要求 :时间限制:1000MS 内存限制:10000KB
通过次数(Accepted):3 提交次数(Submit):24

说明:
输入
第一行是一个表示测试用例次数的整数T(1<=T<=20),接下来是T个测试用例。每个测试用例的第一行是一个整数N,第二行包含N个整数代表每个人过河的时间。不会超过1000个人(即N<=1000)并且每个人的过河时间不会超过100秒。

输出
每一个测试用例,输出N个人过河所用的最短总时间。

输入示例
1
4
1 5 2 10

输出示例
17
求代码… 哪位高手有的。往赐教 ……

1.正确的算法:
如果n=3, 过河时间为A+B+C
如果n<=2, 好算, 不费口舌了

如果n>=4, 这个是重点:
每次优先考虑把最慢两人送过河
把n人中最快两人记为A,B, 最慢两人记为C,D(过河时间A<B<C<D), n人问题实质上转换为4人过河问题, 参考到4人过河时的优化,
记AB过河, A回, CD过河, B回, 为方法X, 实质是利用最快两人进行优化, 耗时A+2B+D
记AD过河, A回, AC过河, A回, 为方法y, 实质是利用最快一人来过河, 耗时2A+C+D
每次比较这两个方法, 如果x快, 使用x方法, 如果y快, 则用y, 并且, 一旦某次使用y方法后, 以后都不用比较了, 全部使用y方法过河

2.算法正确性证明:
为什么每次先让最慢两人过河? 因为他们迟早要过河...早过晚过一样, 而晚过的话, 有可能时间不能被优化, 所以选择最先过
为什么是两人, 不是三人? 因为这船一次只能两人, 三人问题和两人问题的优化一样, 所以一次考虑三人毫无意义, 同理, 三人以上不加考虑

为什么某次用y过河后不用再比较xy了?
先看这个例子:

1 99 100 101
用x方法是99+1+101+99= 300
y方法是 101+1+100+1 = 203

y比x快的原因是2A+C+D < A+2B+D, 即 A+C<2B
容易想到, 从此以后A+C都会小于2B了(因为C越来越小)

3.补充:
算法分析就到这里了, 至于具体的程序...楼主既然是ACMer, 这个应该不困难
当然, 如果楼主需要的话, 也可以给出程序
温馨提示:内容为网友见解,仅供参考
第1个回答  2008-03-03
最短时间是这样的
以本例子说
最快2人过 时间2
最快人回 时间1
最慢2人过 时间10
最快人回 时间2
最快2人过 时间2
一共17
算法就是这样过河以最快2人和最慢2人交替进行,回来时候都是对岸最快的人回来。

ps:这个是哪里的ACM?
这样写出代码不难吧。
就是先将时间排序,然后按上面算法计算。
第2个回答  2008-03-04
#include<iostream>
#include<algorithm>
using namespace std;
int a[1001];
int main()
{
int t,i,n,fast1,fast2,slow1,slow2,slow3,sum,l,r;
cin>>t;
while(t--)
{
sum=0;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
fast1=a[1];fast2=a[2];slow1=a[n-1];slow2=a[n];slow3=0;
l=1;r=n;
while(n!=0)
{
if(n==1) {sum+=slow2;break;}
if(n==2) {sum+=slow2;break;}
if(n==3) {sum+=(slow2+slow1+fast1);break;}
if(2*fast2>=fast1+slow1) {sum+=(slow1+slow2+2*fast1);r-=2;slow2=a[r];slow1=a[r-1];n-=2;}
else {sum+=2*fast2+fast1+slow2;r-=2;slow2=a[r];slow1=a[r-1];n-=2;}
}
cout<<sum<<endl;
}
return 0;
}
第3个回答  2008-03-03
有些不懂...我也是初学者..进来看看
1
4
1 5 2 10
那么最短时间不应该是
5+1+2+1+10=19 么??
我错了?!``
第4个回答  2008-03-04
试用例次数的整数T是什么
船是两边来回送人,还是单向送人。
看不懂问题

速阅C语言经典考题
C语言经典题目 1、有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?2、一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?3、用*号输出字母C的图案。4、输出9*9口诀。5、利用条件运算符的嵌套来完成此题:学习成绩>=90分...

C语言的8个简单程序(经典例题)新手小白必码!!
【程序一】求两数的最小公倍数和最大公约数 代码如下:【程序二】判断一个数是否为素数 【程序三】计算2至100之间的素数列表 【程序四】输入三个数并找出其中的最大值 【程序五】输出指定字符 【程序六】计算序列1-1\/3+1\/5-1\/7...+1\/101的和 【程序七】输出由星号(*)组成的n行倒三角形...

c语言经典100
您好,c语言经典100题:【程序1】题目:有1,2,3,4个数字,能组成多少个互不相同且无重复数字的三位数 都是多少 1.程序分析:可填在百位,十位,个位的数字都是1,2,3,4.组成所有的排列后再去 掉不满足条件的排列.2.程序源代码:main(){ int i,j,k;printf("\\n");for(i1;i<5;i++)\/*以...

C语言经典题目
把n人中最快两人记为A,B, 最慢两人记为C,D(过河时间A<B<C<D), n人问题实质上转换为4人过河问题, 参考到4人过河时的优化,记AB过河, A回, CD过河, B回, 为方法X, 实质是利用最快两人进行优化, 耗时A+2B+D 记AD过河, A回, AC过河, A回, 为方法y, 实质是利用最快一人来过河, 耗...

C语言经典程序n个人n盏灯第一人关掉所有的灯!第二个人取反!我是用因 ...
include<stdio.h> include<math.h> define Max 100 int main(){ int n; \/\/n个灯,n个人 printf("请输入n的值:");scanf("%d", &n);int a[Max]; \/\/定义一个数组,放置n个灯的状态,0为关灯,1为开灯;for (int i = 0; i < n; i++){ \/\/将所有灯泡对应的状态设为0...

c语言怎么学考试基础知识笔记经典例题题库指针大一期末考试题入门二级...
一、单项选择题 1. C语言的特点不包括 (B) - C语言简洁紧凑,能编复杂程序,对硬件操作直接,移植性强。2. 不正确的C语言标识符是 (D) - 不能以`.`或`.`. 开头。3. 一个C程序由 (B) - 函数组成。4. 算法错误特性描述是 (B) - 有零个或多个输入,输出不限,有穷性和可行性是...

10道经典的C语言例题(含参考程序)
int main(){ int bai_wei,shi_wei,ge_wei,i,sum=0;for(i=100;i<1000;i++){ bai_wei=i\/100;shi_wei=(i%100)\/10;ge_wei=i%10;if(i==pow(bai_wei,3)+pow(shi_wei,3)+pow(ge_wei,3)){ printf("%d ",i);sum++;if(sum%5==0)printf(" ");} } printf(" ");return ...

C语言经典题目分享
int main() { int a,b,c=0;scanf("%d%d",&a,&b);if ((a>=0&&a=0&&b<=10)){ c=a+b;printf ("%d ",c);} else printf("error ");return 0 ;} 求平均年龄 班上有学生若干名,给出每名学生的年龄(整数),求班上所有学生的平均年龄,保留到小数点后两位。Input 第一行有...

C语言编程经典282例,阳阳买苹果
money+=0.8*n;\/\/第一天花的钱 day++;\/\/1天,看到了吧,买2个苹果是第1天,而不是第0天 n*=2;\/\/这条语句你也写错了。计算第二天买的苹果数量 n<100,继续执行循环 money+=0.8*n;\/\/两天花的钱 day++;\/\/2天 n*=2;\/\/计算第三天买的苹果数量 n<100,继续执行,依次类推。直到n...

c语言经典例题有哪些?
探讨C语言经典例题,需要从不同角度入手。C语言的题目种类繁多,具体分为三类:内部处理细节、算法与数据结构、以及项目实践。对于内部处理细节,这类问题主要检验你对C语言本身的理解。例如,你是否知道在数组中"print a[1]"和"print 1[a]"会有何不同结果?这种题虽常见于面试,但实际应用中却较少...

相似回答