C语言大赛题目(带答案)_c语言经典题目带答案
C语言大赛题目(带答案)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“c语言经典题目带答案”。
第1题 歌手大赛问题 题目:青年歌手参加歌曲大奖赛,有10个评委进行打分,试编程求这位选手的平均得分。3种方法:分别要求使用到排序,数组,函数,指针。分析:这道题的核心程序是排序,将评委打的10个分数利用数组按增序(或降序)排列,计算数组中除了第一个和最后一个分数以外的数以外的数的平均分 答案: #include double Aver(int p[],int count)//求出结果,p为整型数组,count为数组大小 { double result=0;for(inti=0;i
1. 11.打鱼还是晒网 中国有句俗语叫“三天打鱼两天晒网”。某人从1990年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。*问题分析与算法设计 根据题意可以将解题过程分为三步: 1)计算从1990年1月1日开始至指定日期共有多少天; 2)由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除; 3)根据余数判断他是在“打鱼”还是在“晒网”; 若余数为1,2,3,则他是在“打鱼” 否则是在“晒网” 在这三步中,关键是第一步。求从1990年1月1日至指定日期有多少天,要判断经历年份中是否有闰年,二月为29天,平年为28天。闰年的方法可以用伪语句描述如下: 如果((年能被4除尽且不能被100除尽)或能被400除尽)则该年是闰年; 否则不是闰年。C语言中判断能否整除可以使用求余运算(即求模)*程序与程序注释 #include int days(struct date day);struct date{ int year;int month;int day;};void main(){ struct date today,term;intyearday,year,day;printf(“Enter year/month/day:”);scanf(“%d%d%d”,&today.year,&today.month,&today.day);/*输入日期*/ term.month=12;/*设置变量的初始值:月*/ term.day=31;/*设置变量的初始值:日*/ for(yearday=0,year=1990;year0&&day<4)printf(“he was fishing at that day.”);/*打印结果*/ elseprintf(“He was sleeping at that day.”);} int days(struct date day){ staticintday_tab[2][13]= {{0,31,28,31,30,31,30,31,31,30,31,30,31,}, /*平均每月的天数*/ {0,31,29,31,30,31,30,31,31,30,31,30,31,}, };inti,lp;lp=day.year%4==0&&day.year%100!=0||day.year%400==0;/*判定year为闰年还是平年,lp=0为平年,非0为闰年*/ for(i=1;i
2. 12.抓交通肇事犯 一辆卡车违反交通规则,撞人后逃跑。现场有三人目击事件,但都没有记住车号,只记下车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前两位不同;丙是数学家,他说:四位的车号刚好是一个整数的平方。请根据以上线索求出车号。*问题分析与算法设计 按照题目的要求造出一个前两位数相同、后两位数相同且相互间又不同的整数,然后判断该整数是否是另一个整数的平方。*程序与程序注释 #include #include void main(){ inti,j,k,c;for(i=1;i<=9;i++)/*i:车号前二位的取值*/ for(j=0;j<=9;j++)/*j:车号后二位的取值*/ if(i!=j)/*判断二位数字是否相异*/ { k=i*1000+i*100+j*10+j;/*计算出可能的整数*/ for(c=31;c*c 3. 14.怎样存钱利最大 假设银行整存整取存款不同期限的月息利率分别为: 0.63% 期限=1年 0.66% 期限=2年 0.69% 期限=3年 0.75% 期限=5年 0.84% 期限=8年 利息=本金*月息利率*12*存款年限。现在某人手中有2000元钱,请通过计算选择一种存钱方案,使得钱存入银行20年后得到的利息最多(假定银行对超过存款期限的那一部分时间不付利息)。*问题分析与算法 为了得到最多的利息,存入银行的钱应在到期时马上取出来,然后立刻将原来的本金和利息加起来再作为新的本金存入银行,这样不断地滚动直到满20年为止,由于存款的利率不同,所以不同的存款方法(年限)存20年得到的利息是不一样的。分析题意,设2000元存20年,其中1年存i1次,2年存i2次,3年存i3次,5年存i5次,8年存i8次,则到期时存款人应得到的本利合计为: 2000*(1+rate1)i1*(1+rate2)i2*(1+rate3)i3*(1+rate5)i5*(1+rate8)i8 其中rateN为对应存款年限的利率。根据题意还可得到以下限制条件: 0 8、i5、i3、i2和i1的组合,代入求本利的公式计算出最大值,就是最佳存款方案。*程序与程序注释 #include #include void main(){ int i8,i5,i3,i2,i1,n8,n5,n3,n2,n1;float max=0,term;for(i8=0;i8max){ max=term;n1=i1;n2=i2;n3=i3;n5=i5;n8=i8;} } printf(“For maxinumprofit,he should so save his money in a bank:”);printf(“ made fixed deposit for 8 year: %d times”,n8);printf(“ made fixed deposit for 5 year: %d times”,n5);printf(“ made fixed deposit for 3 year: %d times”,n3);printf(“ made fixed deposit for 2 year: %d times”,n2);printf(“ made fixed deposit for 1 year: %d times”,n1);printf(“ Toal: %.2f”,max);/*输出存款方式*/ } *运行结果 For maxinumprofit,he should so save his money in a bank: made fixed deposit for 8 year: 0times made fixed deposit for 5 year: 4times made fixed deposit for 3 year: 0times made fixed deposit for 2 year: 0times made fixed deposit for 1 year: 0times Total:8841.01 可见最佳的存款方案为连续四次存5年期。 4. 51.谁是窃贼 公安人员审问四名窃贼嫌疑犯。已知,这四人当中仅有一名是窃贼,还知道这四人中每人要么是诚实的,要么总是说谎的。在回答公安人员的问题中: 甲说:“乙没有偷,是丁偷的。” 乙说:“我没有偷,是丙便的。” 丙说:“甲没有偷,是乙偷的。” 丁说:“我没有偷。” 请根据这四人的答话判断谁是盗窃者。*问题分析与算法设计 假设A、B、C、D分别代表四个人,变量的值为1代表该人是窃贱。由题目已知:四人中仅有一名是窃贱,且这四个人中的每个人要么说真话,要么说假话,而由于甲、乙、丙三人都说了两句话:“X没偷,X偷了”,故不论该人是否说谎,他提到的两人中必有一人是小偷。故在列条件表达式时,可以不关心谁说谎,谁说实话。这样,可以列出下列条件表达式: 甲说:”乙没有偷,是丁偷的。” B+D=1 乙说:“我没有偷,是丙偷有。” B+C=1 丙说:“甲没有偷,是乙偷的。” A+B=1 丁说:“我没有偷。” A+B+C+D=1 其中丁只说了一句话,无法判定其真假,表达式反映了四人中仅有一名是窃贱的条件。*程序与程序注释 #include void main(){ inti,j,a[4];for(i=0;i<4;i++)/*假定只有第i个人为窃贱*/ { for(j=0;j<4;j++)/*将第i个人设置为1表示窃贱,其余为0*/ if(j==i)a[j]=1;else a[j]=0;if(a[3]+a[1]==1&&a[1]+a[2]==1&&a[0]+a[1]==1)/*判断条件是否成立*/ { printf(“The thief is ”);/*成立*/ for(j=0;j<=3;j++)/*输出计算结果*/ if(a[j])printf(“%c.”,j+'A');printf(“”);} } } *运行结果 The thief is B.(乙为窃贱。) 69.魔术师的猜牌术(1)魔术师利用一副牌中的13张黑桃,预先将它们排好后迭在一起,牌面朝下。对观众说:我不看牌,只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?你们就看。魔术师将最上面的那张牌数为1,把它翻过来正好是黑桃A,将黑桃A放在桌子上,然后按顺序从上到下数手上的余牌,第二次数1、2,将第一张牌放在这迭牌的下面,将第二张牌翻过来,正好是黑桃2,也将它放在桌子上,第三次数1、2、3,将前面两张依次放在这迭牌的下面,再翻第三张牌正好是黑桃3。这样依次进行将13张牌全翻出来,准确无误。问魔术师手中的牌原始顺序是怎样安排的? *问题分析与算法设计 题目已经将魔术师出牌的过程描述清楚,我们可以利用倒推的方法,很容易地推出原来牌的顺序。人工倒推的方法是:在桌子上放13空盒子排成一圈,从1开始顺序编号,将黑桃A放入1号盒子中,从下一个空盒子开始对空的盒子计数,当数到第二个空盒子时,将黑桃2放入空盒子中,然后再从下一个空盒子开始对空盒子计数,顺序放入3、4、5...,直到放入全部3张牌。注意在计数时要跳过非空的盒子,只对空盒子计数。最后牌在盒子中的顺序,就是魔术师手中原来牌的顺序。这种人工的方法是行之有效的,计算机可以模拟求解。*程序与程序注释 #include int a[14];void main(){ inti,n,j=1;/*j:数组(盒子)下标,初始时为1号元素*/ printf(“The original order of cards is:”);for(i=1;i13)j=1;/*由于盒子构成一个圈,j超过最后一个元素则指向1号元素*/ if(a[j])j++;/*跳过非空的盒子,不进行计数*/ else{ if(n==i)a[j]=i;/*若数到第i个空盒子,则将牌放入空盒中*/ j++;n++;/*对空盒计数,数组下标指向下一个盒子*/ } }while(n<=i);/*控制空盒计数为i*/ } for(i=1;i<=13;i++)/*输出牌的排列顺序*/ printf(“%d ”,a);printf(“”);} *运行结果 The original order of cards is:1 8 2 5 10 3 12 11 9 4 7 6 13 70.魔术师的猜牌术(2)魔术师再次表演,他将红桃和黑桃全部迭在一起,牌面朝下放在手中,对观众说:最上面一张是黑桃A,翻开后放在桌上。以后,从上至下每数两张全依次放在最底下,第三张给观众看,便是黑桃2,放在桌上后再数两张依次放在最底下,第三张给观众看,是黑桃3。如此下去,观众看到放在桌子上牌的顺序是: 黑桃 A 2 3 4 5 6 7 8 9 10 J Q K 红桃 A 2 3 4 5 6 7 8 9 10 J Q K 问魔术师手中牌的原始顺序是什么? *问题分析与算法设计 本题可在上题的基础上进行编程,不同的在于计数的方法和牌的张数,这些并不影响我们求解题目的思路,仍可按照倒推的方法,得到原来魔术师手中的牌的顺序。*程序与程序注释 #include int a[27];void main(){ inti,n,j=1;a[1]=1;/*初始化第一张牌*/ printf(“The original order of cards is:(r:rad b:block):”);for(i=2;i26)j=1;/*超过最后一个元素则指向1号元素*/ if(a[j])j++;/*跳过非空的盒子,不进行计数*/ else{ if(n==3)a[j]=i;/*若数到第3个空盒子,则将牌放入空盒中*/ j++;n++;/*对空盒计数,数组下标指向下一个盒子*/ } }while(n13? 'r':'b');printf(“%d ”,a>13? a-13:a);if(i==13)printf(“”);} printf(“”);} *运行结果 The original order of cards is:(r:rad b:black): b1 r6 b10 b2 r12 r3 b3 b11 r9 b4 r7 b12 b5 r4 r13 b6 b13 r11 b7 r5 r1 b8 r8 r10 b9 r2 75.10个小孩分糖果 十个小孩围成一圈分糖果,老师分给第一个小孩10块,第二个小孩2块,第三个小孩8块,第四个小孩22块,第五个小孩16块,第六个小孩4块,第七个小孩10块,第八个小孩6块,第九个小孩14块,第十个小孩20块。然后所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块。问经过这样几次后大家手中的糖的块数一样多?每人各有多少块糖? *问题分析与算法设计 题目描述的分糖过程是一个机械的重复过程,编程算法完全可以按照描述的过程进行模拟。*程序与程序注释 #include void print(int s[]);int judge(int c[]);int j=0;void main(){ static int sweet[10]={10,2,8,22,16,4,10,6,14,20};/*初始化数组数据*/ inti,t[10],l;printf(“ child”);printf(“ round 1 2 3 4 5 6 7 8 9 10”);printf(“.............................”);print(sweet);/*输出每个人手中糖的块数*/ while(judge(sweet))/*若不满足要求则继续进行循环*/ { for(i=0;i<10;i++)/*将每个人手中的糖分成一半*/ if(sweet%2==0)/*若为偶数则直接分出一半*/ t=sweet=sweet/2;else /*若为奇数则加1后再分出一半*/ t=sweet=(sweet+1)/2;for(l=0;l<9;l++)/*将分出的一半糖给右(后)边的孩子*/ sweet[l+1]=sweet[l+1]+t[l];sweet[0]+=t[9];print(sweet);/*输出当前每个孩子中手中的糖数*/ } } int judge(int c[]){ inti;for(i=0;i<10;i++)/*判断每个孩子手中的糖是否相同*/ if(c[0]!=c)return 1;/*不相同返回 1*/ return 0;} void print(int s[])/*输出数组中每个元素的值*/ { int k;printf(“ %2d ”,j++);for(k=0;k<10;k++)printf(“%4d”,s[k]);printf(“”);}--------------------作者:huang01--发布时间:2004-10-21 17:16:52--5. 76.小明买书 小明假期同爸爸一起去书店,他选中了六本书,每本书的单价分别为:3.1,1.7,2,5.3,0.9和7.2。不巧的是,小明的爸爸只带了十几块钱,为了让小明过一个愉快的假期,爸爸扔然同意买书,但提邮购一个要求,要小明从六本书中选出若干本,使得单价相加所得的和同10最接近。你能够帮助小明解决这个问题吗? *问题分析与算法设计 分析题意,可将题目简化为:从六个数中选出若干个求和,使得和与10的差值最小。题目中隐含两个问题,其一是怎样从六个数中选出若干个数;其二是求与10的差。从六个数中选出若干个数实质是从六个数中选出若干个进行组合。每个数在组合过程中只有两种情况:要么是选中参加求和,要么是没选中不参加求和。这样就可以使用六重循环对每个数是否参加求和进行全部可能情况的组合。关于求与10的差值应当注意的是:差值的含义是指差的绝对值。例如:“9-10=-1“和”11-10=1“,但9和11这两者与10的差值都是1。若认为”9“与”10的差值为-1就错了。*程序与程序注释 #include #include void main(){ int d[6],m,i,j;long b[63],flag;float c[6],min,x;printf(”Please enter the prices of 6 books:“);for(i=0;i=0;j--)/*flag:将六个数的组合用对应的一个十进制位表示 x:对应六个数组合的和*/ { x+=c[j]*d[j];flag=flag*10+d[j];} x=((x-10>0)? x-10:10-x);/*x: 组合的和与10的差*/ if(min1.e-6)/*对新的min的处理*/ { min=x;b[0]=flag;i=1;} else if(fabs((double)x-min)0;j++,flag/=10)if(flag%10)/*将b[]中存的标记flag还原为各个数的组合*/ if(flag>1)printf(”%.2f+“,c[j]);elseprintf(”%.2f“,c[j]);} } *运行结果 Please enter the prices of 6 books:3.1 1.7 2.0 5.3 0.9 7.2 10(+-)0.10=2.00+0.90+7.20 10(+-)0.10=1.70+2.00+5.30+0.90 10(+-)0.10=3.10+1.70+5.30 *思考题 可以看出,程序中求六个数所能产生全部组合的算法并不好,使用六重循环进行处理使程序显得不够简洁。可以设计出更通用、优化的算法产生全部组合。6. 77.波松瓦酒的分酒趣题 法国著名数学家波瓦松在表年时代研究过一个有趣的数学问题:某人有12品脱的啤酒一瓶,想从中倒出6品脱,但他没有6品脱的容器,仅有一个8品脱和5品脱的容器,怎样倒才能将啤酒分为两个6品脱呢? *问题分析与算法设计 将12品脱酒 8品脱和5品脱的空瓶平分,可以抽象为解不定方程: 8x-5y=6 其意义是:从12品脱的瓶中向8品脱的瓶中倒x次,并且将5品脱瓶中的酒向12品脱的瓶中倒y次,最后在12品脱的瓶中剩余6品脱的酒。用a,b,c代表12品脱、8品脱和5品脱的瓶子,求出不定方程的整数解,按照不定方程的意义则倒法为: a-> b-> c->a x y 倒酒的规则如下: 1)按a-> b-> c->a的顺序; 2)b倒空后才能从a中取 3)c装满后才能向a中倒 按以上规则可以编写出程序如下: *程序与程序注释 #include voidgetti(inta,inty,int z);inti;/*最后需要分出的重量*/ void main(){ inta,y,z;printf(”input Full a,Emptyb,c,Get i:“);/*a 满瓶的容量 y:第一个空瓶的容量 z:第二个空瓶的容量*/ scanf(”%d%d%d%d“,&a,&y,&z,&i);getti(a,y,z);/*按a-> y-> z-> a的操作步骤*/ getti(a,z,y);/*按a-> z-> y-> a的步骤*/ } void getti(inta,inty,int z)/*a:满瓶的容量 y:第一个空瓶的容量 z:第二个空瓶的容量*/ { int b=0,c=0;/* b:第一瓶实际的重量 c:第二瓶实际的重量*/ printf(” a%db%dc%d %4d%4d%4d“,a,y,z,a,b,c);while(a!=i||b!=i&&c!=i)/*当满瓶!=i或另两瓶都!=i*/ { if(!b){ a-=y;b=y;} /*如果第一瓶为空,则将满瓶倒入第一瓶中*/ else if(c==z){ a+=z;c=0;} /*如果第二瓶满,则将第二瓶倒入满瓶中*/ else if(b>z-c)/*如果第一瓶的重量>第二瓶的剩余空间*/ { b-=(z-c);c=z;} /*则将装满第二瓶,第一瓶中保留剩余部分*/ else{ c+=b;b=0;} /*否则,将第一瓶全部倒入第二瓶中*/ printf(” %4d %4d %4d",a,b,c);} }