C语言编程竞赛训练试题参考答案.docx
《C语言编程竞赛训练试题参考答案.docx》由会员分享,可在线阅读,更多相关《C语言编程竞赛训练试题参考答案.docx(26页珍藏版)》请在冰豆网上搜索。
C语言编程竞赛训练试题参考答案
C/C++语言编程竞赛训练题(部分)
1.编辑工具一般都具有字符串“查找”功能,试编程实现字符串的查找并统计匹配的次数。
要求如下:
(1)查找字符串以逗号为分隔符,若遇逗号,则从逗号后的字符重新开始查找;
(2)区分字母大小写;
(3)能支持通配符"?
"和"*"查找,其中"?
"可表示任意1个字符(为含空字符),"*"代表任意N个字符(N≥0)。
输入描述:
首先输入要查找的字符串个数M,接着输入M个要查找的字符串,每个字符串占一行,最后是被查找的文本。
输出描述:
要求分行输出每个字符串在文中出现的次数。
运行后若输入:
3
A
D
a
D,abb,DccABV,AAAAABB,accc,Dabc
则结果输出为:
4
3
2
参考答案:
#include"iostream.h"
#include"string.h"
char*Strstr(chars[],constcharsub[])//自定义
{//s串中查找是否有sub子串内容,找到返回其起始位置,sub允许含'?
'通配符,不允许含'*'
char*p;inti=0,j=0,k=0;//abbbcdefbcdebb?
f//abbbcdefbcde?
?
?
fvr
if(strlen(sub)>strlen(s))returnNULL;//若子串更长则退出
while(sub[i]=='?
')i++,k++;//跳过子串前导'?
'
if(sub[i]==0)returns;//若已经匹配返回其位置
if((p=strchr(s+k,sub[i]))==NULL)returnNULL;//若不含子串字符则退出
while((p[j]==sub[i]||sub[i]=='?
')&&sub[i]&&p[j])j++,i++;//有效字符开始匹配
if(sub[i]==0)returnp-k;//若匹配返回其位置
elsereturnStrstr(p-k+1,sub);//否则从其下一位置查找是否有匹配位置
}
intSearch(constchars[],constcharsub[])//在s串中查找sub子串出现次数
{
char*p,t[80],s0[80];intn=0;
strcpy(t,s);strcpy(s0,sub);//备份文本,abbbcdefbcdebb*fvr?
if((p=strstr(s0,"*"))!
=NULL)//含'*'情况(不考虑同时含'?
')
{*p=0;returnstrstr(t,s0)!
=NULL;}//含或不含'?
'情况
while((p=Strstr(t,s0))!
=NULL){n++;strcpy(t,p+strlen(s0));}
returnn;
}
intSch(constchars[],constcharsub[])
{//abcde\0defg,abcdebcd
char*p,t[80];strcpy(t,s);//备份文本到t
if((p=strstr(t,","))!
=NULL)//判断文本中含逗号,若有则以此分界,
{*p=0;p++;returnSearch(t,sub)+Sch(p,sub);}//逗号前部分匹配次数+逗号后部分匹配次数
else{returnSearch(t,sub);}//不含逗号直接返回匹配次数
}
voidmain()
{
intn,i;chars[80];char**p;
cin>>n;cin.getline(s,80);
p=newchar*[n];
for(i=0;i{
cin.getline(s,80);
p[i]=newchar[strlen(s)+1];
strcpy(p[i],s);
}
cin.getline(s,80);//读被查找的文本
for(i=0;i}
2.平面上任取n个点,可以确定一个多边形。
在计算机中单击鼠标即可获得点的,并以此确定多边形。
现要求通过输入三个点坐标值来确定一个三角形,并求这三个点所围成的三角形的面积(若这三个点不能确定一个三角形,则输出“Noexist”)。
输入描述:
先输入一个整数,表示后面有几组三角形坐标值;接着每行两个数,分别代表一个点的横坐标和纵坐标,三行一组。
输出描述:
先要输出三角形的序号,再输出面积。
运行后若输入:
2
00
05
22
11
14
18
则结果输出为:
5
Noexist
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①2
00
05
22
11
14
18
;5
Noexist
;10;10
②0;0,;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
求三角形面积参考答案:
#include"stdio.h"
#include"math.h"
doubleDis(doublex1,doubley1,doublex2,doubley2)
{returnsqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
voidsjx()
{
floatx1,y1,x2,y2,x3,y3;
floata,b,c,p,s;
scanf("%f%f%f%f%f%f",&x1,&y1,&x2,&y2,&x3,&y3);
a=Dis(x1,y1,x2,y2);b=Dis(x1,y1,x3,y3);c=Dis(x2,y2,x3,y3);
p=(a+b+c)/2;
s=sqrt(p*(p-a)*(p-b)*(p-c));
if(fabs(s)<1e-6)printf("Noexist\n");elseprintf("%g\n",s);
}
voidmain()
{
intn,i;scanf("%d",&n);
for(i=1;i<=n;i++)sjx();
}
求四边形面积参考答案:
#include"stdio.h"
#include"math.h"
doubleDis(doublex1,doubley1,doublex2,doubley2)
{returnsqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
floatsjx(doublex1,doubley1,doublex2,doubley2,doublex3,doubley3)
{
floata,b,c,p,s;
a=Dis(x1,y1,x2,y2);b=Dis(x1,y1,x3,y3);c=Dis(x2,y2,x3,y3);
p=(a+b+c)/2;
s=sqrt(p*(p-a)*(p-b)*(p-c));
returns;
}
voidsbx()
{
floatx1,y1,x2,y2,x3,y3,x4,y4,s1,s2,s3,s4;
scanf("%f%f%f%f%f%f%f%f",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
s1=sjx(x1,y1,x2,y2,x3,y3);s2=sjx(x1,y1,x3,y3,x4,y4);
s3=sjx(x1,y1,x2,y2,x4,y4);s4=sjx(x2,y2,x3,y3,x4,y4);
if(fabs(s1)<1e-6||fabs(s2)<1e-6||fabs(s3)<1e-6||fabs(s4)<1e-6)
printf("Noexist\n");
else
printf("%g\n",s1+s2<=s3+s4?
s1+s2:
s3+s4);
}
voidmain()
{
intn,i;scanf("%d",&n);
for(i=1;i<=n;i++)sbx();
}
3.某研究所研发了一种除草药水,但其药效会随使用次数降低。
经统计,若每次使用M剂量(M为整数),则第一次使用能除M棵草,第二次使用只能除M/2棵草,第三次使用只能除M/3棵草,…,第N次使用只能除M/N棵草。
现要统计M剂量药、使用N次共能除多少棵草。
例如,若剂量为5,使用6次,则可除草棵数为:
5/1+5/2+5/3+5/4+5/5+5/6=10
输入描述:
先输入若干行测试数据,每行包含两个整数MN,分别代表剂量和使用次数,直到输入00表示结束。
输出描述:
输出每组测试数据可除草棵数。
运行后若输入:
2
56
62
则结果输出为:
10
9
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①56
62
00
;10
9
;10;10
②0;0,;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案:
#include"stdio.h"
#include"math.h"
doublef(longm,longn)
{
inti,k,j;doubles=0;k=sqrt(m);
for(i=1;i<=k;i++){if(i>n)returns;s+=m/i;}
j=k;
for(i=k-1;i>0;i--)
if(j+m/i-m/(i+1)else{s+=i*(n-j);returns;}
returns;
}
voidmain()
{
longm,n,i;doubles=0;
scanf("%d%d",&m,&n);
while(m&&n)
{
s=f(m,n);//效率高
//for(s=0,i=1;i<=n;i++)s+=m/i;//效率低
printf("%g\n",s);
scanf("%d%d",&m,&n);
}
}
4.小明在处理一张图像,他把图像中的点写成(x,y,1),然后乘上矩阵
,于是图像向右、向下分别移动了20、30个像素。
接着他把图像中的每一个点(x,y,1)都乘上矩阵
,结果图像又旋转了30弧度。
小明发现了矩阵的神奇,他准备计算矩阵斜下线元素的积(如果斜下线到右边,则继续从左边的下一行的第一个元素开始)。
如
,有三条斜下线,积分别为1*4*3、3*6*7、-2*5*0。
输入描述:
输入的第一个数n代表矩阵的阶,接着n行,每行n个数;接着输入另一个n矩阵的信息,直到输入0阶表示结束。
输出描述:
要先输出序号。
运行后若输入:
3
13-2
446
403
2
02
-14
0
则结果输出为:
12,72,0,
0,-2,
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①3
13-2
446
403
2
02
-14
0
;12,72,0,
0,-2,
;10;10
②0;0,;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案:
#include"stdio.h"
intJZ()
{
intn,i,j,jj;inta[100][100],s[100],ss=0;
scanf("%d",&n);
for(i=0;ifor(j=0;jfor(j=0;j{
s[j]=1;jj=j;//jj=(jj+1)%n;为斜线乘积,jj=(jj-1+n)%n;为反斜线乘积
for(i=0;iss+=s[j];printf("%d",s[j]);
}
printf("\n");
returnss;
}
voidmain()
{
while(JZ());
}
5.小明在一次机密的场合中无意中看到自己所需要的信息。
但他只能在一张标签的空白处记下这些信息,位置不够。
于是他想了一种方法:
对连续重复的部分用数字表示。
没有连续重复的字符就不变。
如ABBBCC,表示为AB3C2。
输入描述:
输入的每行是一个有字母构成的字符串。
输出描述:
输出是压缩后的字符串。
运行后若输入:
3
ABBBCC
MMMN
DDDFFF
则结果输出为:
AB3C2
M3N
D3F3
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①3
ABBBCC
MMMN
DDDFFF
;AB3C2
M3N
D3F3
;10;10
②0;0,;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案(C++):
#include"iostream.h"
#include"stdio.h"
voidYS(chars[])
{
intn=0,i=0;charc=s[i];
do
{
if(c==s[i])n++;//相同累计个数n
else//不同输出上次字符,n>1输出n,然后再计新字符
{cout<1)cout<}
while(s[i++]);//比完'\0'后结束
cout<}
voidmain()
{
intn,i;chars[80];cin>>n;cin.getline(s,80);
for(i=0;i}
6.军训中甲班n位同学已经按从低到高排好队,现有乙班m位同学(未排好序)要插入一起集训。
请编程实现将乙班同学插入甲班后使队伍仍为从低到高排好的队列。
输入描述:
先输入两个整数nm,分别代表甲班和乙班的人数,然后输入甲班n个同学的身高,接着输入乙班m个同学的身高;接着输入另两个班的信息,直到输入班级人数0表示结束。
输出描述:
输出每组排好的m+n个身高。
运行后若输入:
53
150152158160168
159159153
24
159165
154167166163
00
则结果输出为:
150,152,153,158,159,159,160,168,
154,159,163,165,166,167,
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①53
150152158160168
159159153
24
159165
154167166163
00
;150,152,153,158,159,159,160,168,
154,159,163,165,166,167,
;10;10
②0;0,;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案(C++):
#include
#include"LinkList2.h"
voidBInsA(intn,intm)
{LinkListA;
inti,j,x;
for(i=1;i<=n;i++){cin>>x;A.InsElem(i,x);}//输入表元素
for(j=1;j<=m;j++)
{
cin>>x;
for(i=1;i<=n;i++)if(A[i]>x){A.InsElem(i,x);n++;break;}
if(i>n){A.InsElem(i,x);n++;}
}
A.DispList();//显示表
}
voidmain()
{
intn,m;
cin>>n>>m;
while(n&&m){BInsA(n,m);cin>>n>>m;}
}
7.某电视台有一娱乐节目,主持人让观众猜商品的价格,若观众能在规定的时间内猜中商品的价格即可获得该商品。
例如,有一精美的水壶(假设实际价格为282元,事先观众不知道),观众只知道在市面上可能的价格范围为100到400元。
此时若观众猜的价格为300元,主持人会告诉观众“大了”;若观众猜的价格为200元,主持人会告诉观众“小了”;直到在规定的时间内观众猜中了商品的价格。
现请你编程模拟猜商品价格的过程,要求在最少的次数内猜中商品的价格(精确到整数)。
输入描述:
先输入一个整数,表示要猜商品价格的次数,然后每行输入三个整数BER,B和E表示观众估计的商品价格范围,R表示实际商品价格。
输出描述:
输出每种商品你所猜的价格。
运行后若输入:
2
100400282
12015
则结果输出为:
250,325,287,268,277,282,
10,15,
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①2
100400282
12015
;250,325,287,268,277,282,
10,15,
;10;10
②1243728509ABabcdCeDF;2,4,2,8,0,1,3,7,5,9,A,B,C,D,F,a,b,c,d,e,;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案(C++):
#include"iostream.h"
voidCJ(intB,intE,intR)
{
intm;
while(B{
m=(B+E)/2;cout<if(R==m)break;//猜对退出
else//实价比中间数m小,则用m-1止点,否则用m+1作起点
{if(R}
cout<}
voidmain()
{
intn,i,B,E,R;cin>>n;
for(i=0;i>B>>E>>R;CJ(B,E,R);}
}
8.一群小朋友外出郊游,并分组做游戏。
要求每组人数一致。
现有n个小朋友,有几种分法。
输入描述:
输入正整数,代表小朋友的人数n,以0结束。
输出描述:
先要输出序号,然后输出分成几组,每组多少人,有多少种情况都要输出。
运行后若输入:
5
6
0
则结果输出为:
5能被分成5组、每组包含1人
6能被分成6组、每组包含1人
6能被分成3组、每组包含2人
6能被分成2组、每组包含3人
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①5
6
0
;5能被分成5组、每组包含1人
6能被分成6组、每组包含1人
6能被分成3组、每组包含2人
6能被分成2组、每组包含3人
;10;10
②0;0;10;0
③30;35;10;0
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案(C):
#include"stdio.h"
voidWS(intx)
{
inti;
for(i=x;i>1;i--)
if(x%i==0)printf("%d能被分成%d组、每组包含%d人\n",x,i,x/i);
}
voidmain()
{
intx;
scanf("%d",&x);
while(x){WS(x);scanf("%d",&x);}
}
9.编写程序判断算术表达式的括号(大括号、方括号、圆括号三种)是否匹配。
输入描述:
先输入一个整数N,表示要判断的表达式个数,然后N行表达式。
输出描述:
输出每种商品你所猜的价格。
运行后若输入:
2
{[(3+2)f]/k}
}[(dk)f]kk}
则结果输出为:
匹配
不匹配
请在/*【*/和/*】*/之间编写程序。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①1
{[(dk)f]kk}
;匹配;10;2
②1
a(d[ds{d}s]d)
;匹配;10;4
③1
{[{}s]d)
;不匹配;10;4
④42;37;10;0
⑤17;null;10;0
;10;5;10;0
参考答案(C++):
#include
#include"sqStack2.h"
intMatch(char*str)
{inti=0;charc;
sqStackS;
while(c=str[i++])
switch(c)
{
case'{':
case'[':
case'(':
S.Push(c);break;
case'}':
if(S.GetTop()=='{')S.Pop();elsereturn0;break;
case']':
if(S.GetTop()=='[')S.Pop();elsereturn0;break;
case')':
if(S.GetTop()=='(')S.Pop();elsereturn0;
}
returnS.Empty();
}
voidmain()
{
inti,n;chars[80];
cin>>n;
for(i=0;i{
cin>>s;
if(Match(s))cout<<"匹配";elsecout<<"不匹配";
}
}
10.编程实现过滤器功能,例如,若是整数,通过此过滤器分离出偶数和奇数,若是字母,通过此过滤器分离出大写和小写字母等。
要求分离后两部分的顺序不变。
运行后若输入:
1234567890
aABbCcDEde
则结果输出为:
2,4,6,8,0,1,3,5,7,9,A,B,C,D,E,a,b,c,d,e,
请在/*【*/和/*】*/之间的空白处填入适当语句或式子。
注意:
不要删除或增加/*【*/和/*】*/。
/***源程序***/
/*【*/
/*】*/
①1234567890aABbCcDEde;2,4,6,8,0,1,3,5,7,9,A,B,C,D,E,a,b,c,d,e,;10;3
②1243728509ABabcdCeDF;