c语言巧题
只有一个简单的思路,一起讨论一下:
第1个小孩给他一个(谁让他抢在前面呢:)
后面的小孩依次按规矩来,看应该给几个,可爱值高呢,就加一块,否则就减一块。
如果发现减到零了,那就倒回去,前面的人补一块。当然,不是全部补,只要补发到可爱值较高的地方就可以了。实际只需要计算一个总数,所以可以预先算好,直接加到总数中就行了。
开始时,第1个小孩1块糖,待补发的数量=0
第2个小孩先给2块糖,由于可爱值开始变高,待补发的数量=1
每3个小孩先给1块糖,由于可爱值变低,待补发的数量+1。
第4个小孩可爱值变低,待补发总数+1,照说应该给0块糖,当然不行,补发一块,前面的也都补一块,补3块。这个待补发数量还不能归零。当前第4个小孩的糖数应该修正成1。
第5个小孩给2块糖,由于可爱值开始变高,补发数量归零=1。
1+2+1+0+(3)+2=9
大体的思路应该就是这个样子。
② C语言经典题目
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, 这个应该不困难
当然, 如果楼主需要的话, 也可以给出程序
③ 一道c语言的题目:计算a、b之间所有奇数的和
一、算法分析:
要计算a b之间所有奇数和,那么最朴素的算法可以设计如下:
1、输入a,b值;
2、循环遍历a b之间的所有数值,如果为奇数,则累加;
3、输出结果。
二、算法优化:
1、由于连续奇数之间差值为2,所以可以判断出第一个奇数,然后依次加2得到所有奇数,将所有奇数累加即可。
2、连续奇数属于等差数列,所以可以利用等差数列求和公式,更快捷的得到结果。
三、参考代码:
1、原始算法代码:
#include<stdio.h>
intadd(inta,intb)
{
intm,n,s=0;
if(a<b)m=a,n=b;
elsem=b,n=a;//判断ab大小,增加健壮性。
for(;m<=n;m++)
if(m%2==1)s+=m;//判断并累加奇数。
returns;//返回结果。
}
intmain()
{
inta,b;
scanf("%d%d",&a,&b);//输入a,b值。
printf("%d ",add(a,b));//计算并输出结果。
return0;
}
2、优化算法1:
#include<stdio.h>
intadd(inta,intb)
{
intm,n,s=0;
if(a<b)m=a,n=b;
elsem=b,n=a;//判断ab大小,增加健壮性。
if(m%2==0)m+=1;//找到第一个奇数。
for(;m<=n;m+=2)//仅遍历奇数。
s+=m;//累加奇数。
returns;//返回结果。
}
intmain()
{
inta,b;
scanf("%d%d",&a,&b);//输入a,b值。
printf("%d ",add(a,b));//计算并输出结果。
return0;
}
3、优化算法2:
#include<stdio.h>
intadd(inta,intb)
{
intm,n,s=0;
if(a<b)m=a,n=b;
elsem=b,n=a;//判断ab大小,增加健壮性。
if(m%2==0)m+=1;//找到第一个奇数。
if(n%2==0)n-=1;//找到最后一个奇数。
s=(m+n)*((n-m)/2+1)/2;//根据等差数列求和公式计算和。
returns;//返回结果。
}
intmain()
{
inta,b;
scanf("%d%d",&a,&b);//输入a,b值。
printf("%d ",add(a,b));//计算并输出结果。
return0;
}
④ c语言题目:乒乓球比赛
太强大了,
#include "stdio.h"
void main()
{
char i,j,k;/*i是a的对手,j是b的对手,k是c的对手*/
for(i='x';i<='z';i++)//i有三种对阵情况x-a,y-a,z-a,用循环遍历
for(j='x';j<='z';j++)//j有三种对阵情况x-b,y-b,z-b,用循环遍历
{
if(i!=j)//表示i 、j 不能为x,y,z三人中的同一个人
for(k='x';k<='z';k++)//k有三种对阵情况x-c,y-c,z-c,用循环遍历
{
if(i!=k&&j!=k)//表示k、i、j不能为x,y,z三人中的同一个人
{
if(i!='x'&&k!='x'&&k!='z')//此乃题目条件:A说他不和X比(a!=x),而i 又非跟a比,所以i!='x';C说他不和X、Z比。即:i!='x'且k!='x'且k!='z'(同理)
printf("order is a--%c\tb--%c\tc--%c\n",i,j,k);//经过以上排列,选择,最终确定对手组合
}
}
}
}