国信蓝桥杯比赛试题与答案.docx
《国信蓝桥杯比赛试题与答案.docx》由会员分享,可在线阅读,更多相关《国信蓝桥杯比赛试题与答案.docx(14页珍藏版)》请在冰豆网上搜索。
国信蓝桥杯比赛试题与答案
2012第三届蓝桥杯软件大赛C/C++语言本科组答案
第一题:
假设有两种微生物X和Y
X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)。
一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y。
现在已知有新出生的X=10,Y=89,求60分钟后Y的数目。
如果X=10,Y=90呢?
本题的要求就是写出这两种初始条件下,60分钟后Y的数目。
题目的结果令你震惊吗?
这不是简单的数字游戏!
真实的生物圈有着同样脆弱的性质!
也许因为你消灭的那只Y就是最终导致Y种群灭绝的最后一根稻草!
1#include
2usingnamespacestd;
3
4intmain()
5{
6intx=10,y=90;
7inttime=60,k;
8for(k=1;k<=time;k++)
9{
10y-=x;
11if(k%2==0)y*=2;
12if(k%3==0)x*=2;
13//printf("%dtime:
\tx=%d\ty=%d\n",k,x,y);
14}
15printf("y=%d\n",y);
16}
消除行号
最后算出的结果,第一种情况是个巨大的负数:
-979369984,其实就是等于0。
第二种情况是94371840。
第二题:
ABCDE*?
=EDCBA
“ABCDE代表不同的数字,问号也代表某个数字!
"
1#include
2usingnamespacestd;
3
4intmain()
5{
6inta,b,c,d,e;
7for(a=0;a<10;a++)
8{
9for(b=0;b<10;b++)
10{
11if(b==a)continue;
12for(c=0;c<10;c++)
13{
14if(c==b||c==a)continue;
15for(d=0;d<10;d++)
16{
17if(d==c||d==b||d==a)continue;
18for(e=0;e<10;e++)
19{
20if(e==d||e==c||e==b||e==a)continue;
21if((a+b*10+c*100+d*1000+e*10000)%(a*10000+b*1000+c*100+d*10+e)==0)
22{
23printf("%d%d%d%d%d\n",a,b,c,d,e);
24}
25}
26}
27}
28}
29}
30}
这样得出的结果有三个:
02178、04356、21978
第三题:
有一群海盗(不多于20人),在船上比拼酒量。
过程如下:
打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。
再打开一瓶酒平分,又有倒下的,再次重复......直到开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。
当第4瓶酒平分喝下后,大家都倒下了。
等船长醒来,发现海盗船搁浅了。
他在航海日志中写到:
“......昨天,我正好喝了一瓶.......奉劝大家,开船不喝酒,喝酒别开船......”
请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。
如果有多个可能的答案,请列出所有答案,每个答案占一行。
格式是:
人数,人数,...
例如,有一种可能是:
20,5,4,2,0
1#include
2usingnamespacestd;
3
4intmain()
5{
6inta,b,c,d;
7for(a=20;a>=4;a--)
8{
9for(b=a-1;b>=3;b--)
10{
11for(c=b-1;c>=2;c--)
12{
13for(d=c-1;d>=1;d--)
14{
15if(1.0/a+1.0/b+1.0/c+1.0/d==1)
16printf("%d,%d,%d,%d,0\n",a,b,c,d);
17}
18}
19}
20}
21}
消除行号
最后算出来的结果有四种,分别是:
“20,5,4,2,0”,“18,9,3,2,0”,“15,10,3,2,0”,“12,6,4,2,0”
第四题:
某电视台举办了低碳生活大奖赛。
题目的计分规则相当奇怪:
每位选手需要回答10个问题(其编号为1到10),越后面越有难度。
答对的,当前分数翻倍;答错了则扣掉与题号相同的分数(选手必须回答问题,不回答按错误处理)。
每位选手都有一个起步的分数为10分。
某获胜选手最终得分刚好是100分,如果不让你看比赛过程,你能推断出他(她)哪个题目答对了,哪个题目答错了吗?
如果把答对的记为1,答错的记为0,则10个题目的回答情况可以用仅含有1和0的串来表示。
例如:
0010110011就是可能的情况。
你的任务是算出所有可能情况。
每个答案占一行。
1#include
2usingnamespacestd;
3
4intans[10];
5
6voidplay(inttime,intscore)
7{
8intk;
9if(time==10)
10{
11if(score==100)
12{
13for(k=0;k<10;k++)
14printf("%d",ans[k]);
15printf("\n");
16}
17}
18else
19{
20ans[time]=1;
21play(time+1,score*2);
22ans[time]=0;
23play(time+1,score-time-1);
24}
25}
26
27intmain()
28{
29memset(ans,0,sizeof(ans));
30play(0,10);
31}
最后的结果是三个:
“1011010000”,“0111010000”,“0010110011”。
第五题:
这道题是代码填空题,目的是把一个矩阵顺时针旋转。
1 2 3 4 13 9 5 1
5 6 7 8 -->1410 6 2
9101112 1511 7 3
13141516 1612 8 4
题目附带的不完整代码:
1voidrotate(int*x,intrank)
2{
3int*y=(int*)malloc(___________________);//填空
4
5for(inti=0;i6{
7y[_________________________]=x[i];//填空
8}
9
10for(i=0;i11{
12x[i]=y[i];
13}
14
15free(y);
16}
17
18intmain(intargc,char*argv[])
19{
20intx[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
21intrank=4;
22
23rotate(&x[0][0],rank);
24
25for(inti=0;i26{
27for(intj=0;j28{
29printf("%4d",x[i][j]);
30}
31printf("\n");
32}
33
34return0;
35}
消除行号
正确的答案是:
sizeof(int)*rank*rank
(i%rank)*rank-(i/rank)+rank-1
第六题:
依旧是补全代码,大数乘法,本来还算比较繁杂的,但是题目当时附了图,变的很简单了
题目附带的不完整代码:
1voidbigmul(intx,inty,intr[])
2{
3intbase=10000;
4intx2=x/base;
5intx1=x%base;
6inty2=y/base;
7inty1=y%base;
8
9intn1=x1*y1;
10intn2=x1*y2;
11intn3=x2*y1;
12intn4=x2*y2;
13
14r[3]=n1%base;
15r[2]=n1/base+n2%base+n3%base;
16r[1]=____________________________________________;//填空
17r[0]=n4/base;
18
19r[1]+=_______________________;//填空
20r[2]=r[2]%base;
21r[0]+=r[1]/base;
22r[1]=r[1]%base;
23}
24
25intmain(intargc,char*argv[])
26{
27intx[]={0,0,0,0};
28
29bigmul(87654321,12345678,x);
30
31printf("%d%d%d%d\n",x[0],x[1],x[2],x[3]);
32
33return0;
34}
答案:
n2/base+n3/base+n4%base
r[2]/base
第七题:
补全代码,有个6*6的棋盘,预先已经放置了一部分棋子,现在要再补充棋子使得每行每列都有3个棋子
1intN=0;
2
3boolCheckStoneNum(intx[][6])
4{
5for(intk=0;k<6;k++)
6{
7intNumRow=0;
8intNumCol=0;
9for(inti=0;i<6;i++)
10{
11if(x[k][i])NumRow++;
12if(x[i][k])NumCol++;
13}
14if(_____________________)returnfalse;//填空
15}
16returntrue;
17}
18
19intGetRowStoneNum(intx[][6],intr)
20{
21intsum=0;
22for(inti=0;i<6;i++)if(x[r][i])sum++;
23returnsum;
24}
25
26intGetColStoneNum(intx[][6],intc)
27{
28intsum=0;
29for(inti=0;i<6;i++)if(x[i][c])sum++;
30returnsum;
31}
32
33voidshow(intx[][6])
34{
35for(inti=0;i<6;i++)
36{
37for(intj=0;j<6;j++)printf("%2d",x[i][j]);
38printf("\n");
39}
40printf("\n");
41}
42
43voidf(intx[][6],intr,intc);
44
45voidGoNext(intx[][6],intr,intc)
46{
47if(c<6)
48_______________________;//填空
49else
50f(x,r+1,0);
51}
52
53voidf(intx[][6],intr,intc)
54{
55if(r==6)
56{
57if(CheckStoneNum(x))
58{
59N++;
60show(x);
61}
62return;
63}
64
65if(______________)//已经放有了棋子
66{
67GoNext(x,r,c);
68return;
69}
70
71intrr=GetRowStoneNum(x,r);
72intcc=GetColStoneNum(x,c);
73
74if(cc>=3)//本列已满
75GoNext(x,r,c);
76elseif(rr>=3)//本行已满
77f(x,r+1,0);
78else
79{
80x[r][c]=1;
81GoNext(x,r,c);
82x[r][c]=0;
83
84if(!
(3-rr>=6-c||3-cc>=6-r))//本行或本列严重缺子,则本格不能空着!
85GoNext(x,r,c);
86}
87}
88
89intmain(intargc,char*argv[])
90{
91intx[6][6]={
92{1,0,0,0,0,0},
93{0,0,1,0,1,0},
94{0,0,1,1,0,1},
95{0,1,0,0,1,0},
96{0,0,0,1,0,0},
97{1,0,1,0,0,1}
98};
99
100f(x,0,0);
101
102printf("%d\n",N);
103
104return0;
105}
消除行号
答案:
NumRow!
=3||NumCol!
=3
f(x,r,c+1)
x[r][c]==1
第八题:
编程题:
这个程序的任务就是把一串拼音字母转换为6位数字(密码)。
我们可以使用任何好记的拼音串(比如名字,王喜明,就写:
wangximing)作为输入,程序输出6位数字。
变换的过程如下:
第一步.把字符串6个一组折叠起来,比如wangximing则变为:
wangxi
ming
第二步.把所有垂直在同一个位置的字符的ascii码值相加,得出6个数字,如上面的例子,则得出:
228202220206120105
第三步.再把每个数字“缩位”处理:
就是把每个位的数字相加,得出的数字如果不是一位数字,就再缩位,直到变成一位数字为止。
例如:
228=>2+2+8=12=>1+2=3
上面的数字缩位后变为:
344836,这就是程序最终的输出结果!
要求程序从标准输入接收数据,在标准输出上输出结果。
输入格式为:
第一行是一个整数n(<100),表示下边有多少输入行,接下来是n行字符串,就是等待变换的字符串。
输出格式为:
n行变换后的6位密码。
1#include
2
3intlitenum(intoldnum)
4{
5intnewnum=0;
6if(oldnum<10)returnoldnum;
7while(oldnum>0)
8{
9newnum+=oldnum%10;
10oldnum/=10;
11}
12returnlitenum(newnum);
13}
14
15intmain()
16{
17intn;
18scanf("%d\n",&n);
19while(n--)
20{
21intsnum[6]={0,0,0,0,0,0};//密码
22chartmpc;
23inttime=0,k;
24/*
25由于题目没有给出输入的字符串的最大长度
26使用while
(1)和getchar()来实现几乎不受限的输入
27*/
28while
(1)
29{
30tmpc=getchar();
31if(tmpc=='\n')break;
32snum[time%6]+=tmpc;
33time++;
34}
35for(k=0;k<6;k++)
36{
37printf("%d",litenum(snum[k]));
38}
39printf("\n");
40}
41return0;
42}
第九题:
足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能。
假设有甲、乙、丙、丁四个球队。
根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表:
甲乙丙丁
甲-0.10.30.5
乙0.9-0.70.4
丙0.70.3-0.2
丁0.50.60.8-
数据含义:
甲对乙的取胜概率为0.1,丙对乙的胜率为0.3,...
现在要举行一次锦标赛。
双方抽签,分两个组比,获胜的两个队再争夺冠军。
(参见【1.jpg】)
请你进行10万次模拟,计算出甲队夺冠的概率。