2012第三届蓝桥杯C语言本科初赛题目 整理 1

第一题:

假设有两种微生物 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 种群灭绝的最后一根稻草!

首先从题目描述上可以猜测第一种情况的答案很可能是0。
虽然只需要写答案,还是需要写代码来计算一下。

我的代码:

01 #include
02 using namespace std;
03  
04 int main()
05 {
06     int x=10,y=90;
07     int time=60,k;
08     for ( k=1;k<=time;k++ )
09     {
10         y -= x ;
11         if ( k%2==0 ) y *= 2;
12         if ( k%3==0 ) x *= 2;
13 //      printf("%dtime:\tx=%d\ty=%d\n",k,x,y);
14     }
15     printf("y = %d\n",y);
16 }

最后算出的结果,第一种情况是个巨大的负数: -979369984,其实就是等于 0 喽。第二种情况是 94371840,果然一个小数字会引起巨大的差别啊。

 

第二题:

ABCDE * ? = EDCBA
“ABCDE代表不同的数字,问号也代表某个数字!”

对于题意理解上出现了一些问题,ABCDE代表不同的数字,那能不能是0呢?A作为首位能不能是0呢?我写的时候认为是可以的。
因为只有5层循环,所以直接for过去了。

我的代码:

01 #include
02 using namespace std;
03  
04 int main()
05 {
06     int a,b,c,d,e;
07     for (a=0;a<10;a++)
08     {
09         for (b=0;b<10;b++)
10         {
11             if (b==a) continue;
12             for (c=0;c<10;c++)
13             {
14                 if (c==b || c==a) continue;
15                 for (d=0;d<10;d++)
16                 {
17                     if (d==c || d==b || d==a ) continue;
18                     for (e=0;e<10;e++)
19                     {
20                         if (e==d || e==c ||e==b || e==a) continue;
21                         if ((a+b*10+c*100+d*1000+e*10000)%(a*10000+b*1000+c*100+d*10+e)==0)
22                         {
23                             printf("%d%d%d%d%d\n",a,b,c,d,e);
24                         }
25                     }
26                 }
27             }
28         }
29     }
30 }

这样得出的结果有三个:02178、04356、21978,前两个都是带前导0的

 

第三题:

有一群海盗(不多于20人),在船上比拼酒量。过程如下:打开一瓶酒,所有在场的人平分喝下,有几个人倒下了。再打开一瓶酒平分,又有倒下的,再次重复…… 直到开了第4瓶酒,坐着的已经所剩无几,海盗船长也在其中。当第4瓶酒平分喝下后,大家都倒下了。
等船长醒来,发现海盗船搁浅了。他在航海日志中写到:“……昨天,我正好喝了一瓶…….奉劝大家,开船不喝酒,喝酒别开船……”
请你根据这些信息,推断开始有多少人,每一轮喝下来还剩多少人。
如果有多个可能的答案,请列出所有答案,每个答案占一行。
格式是:人数,人数,…
例如,有一种可能是:20,5,4,2,0

这个就很简单了,四个递减的正整数 a,b,c,d。1/a+1/b+1/c+1/d=1 即可。考虑到循环的不多,继续暴力 for 循环。

我的代码:

01 #include
02 using namespace std;
03  
04 int main()
05 {
06     int a,b,c,d;
07     for (a=20;a>=4;a--)
08     {
09         for (b=a-1;b>=3;b--)
10         {
11             for (c=b-1;c>=2;c--)
12             {
13                 for (d=c-1;d>=1;d--)
14                 {
15                     if ( 1.0/a+1.0/b+1.0/c+1.0/d == 1)
16                         printf("%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 就是可能的情况。
你的任务是算出所有可能情况。每个答案占一行。

真不知道出题者是什么想法,全是爆搜题,看了下发现有十层。还是拿递归写吧。
我的代码:

01 #include
02 using namespace std;
03  
04 int ans[10];
05  
06 void play(int time,int score)
07 {
08     int k;
09     if (time==10)
10     {
11         if (score==100)
12         {
13             for (k=0;k<10;k++)
14                 printf("%d",ans[k]);
15             printf("\n");
16         }  
17     }
18     else
19     {
20         ans[time]=1;
21         play(time+1,score*2);
22         ans[time]=0;
23         play(time+1,score-time-1);
24     }
25 }
26  
27 int main()
28 {
29     memset(ans,0,sizeof(ans));
30     play(0,10);
31 }

最后的结果是三个:“1011010000”,“0111010000”,“0010110011” 。

 

第五题:

这道题是代码填空题,目的是把一个矩阵顺时针旋转。

1  2   3   4      13   9  5  1

5  6   7   8 –> 14 10  6  2

9 10 11 12      15 11  7  3

13 14 15 16      16 12  8  4

题目附带的不完整代码:

01 void rotate(int* x, int rank)
02 {
03     int* y = (int*)malloc(___________________); // 填空
04  
05     for(int i=0; i
06     {
07         y[_________________________] = x[i];  // 填空
08  }
09  
10     for(i=0; i
11     {
12         x[i] = y[i];
13     }
14  
15     free(y);
16 }
17  
18 int main(int argc, char* argv[])
19 {
20     int x[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
21     int rank = 4;
22  
23     rotate(&x[0][0], rank);
24  
25     for(int i=0; i
26     {
27         for(int j=0; j
28         {
29             printf("%4d", x[i][j]);
30         }
31         printf("\n");
32     }
33  
34     return 0;
35 }

正确的答案应该是:

sizeof(int)*rank*rank

(i%rank)*rank-(i/rank)+rank-1

// 以原第一行进行分析  一行数变为同一列  以原第一列为例,变为同一行。  (i%rank)*rank使列变为行   rank-(i/rank)-1) 使行变为列  

 

第六题:

依旧是补全代码,大数乘法,本来还算比较繁杂的,但是题目当时附了图,变的很简单了

题目附带的不完整代码:

01 void bigmul(int x, int y, int r[])
02 {
03     int base = 10000;
04     int x2 = x / base;
05     int x1 = x % base;
06     int y2 = y / base;
07     int y1 = y % base;
08  
09     int n1 = x1 * y1;
10     int n2 = x1 * y2;
11     int n3 = x2 * y1;
12     int n4 = x2 * y2;
13  
14     r[3] = n1 % base;
15     r[2] = n1 / base + n2 % base + n3 % base;
16     r[1] = ____________________________________________; // 填空
17  r[0] = n4 / base;
18  
19     r[1] += _______________________; // 填空
20  r[2] = r[2] % base;
21     r[0] += r[1] / base;
22     r[1] = r[1] % base;
23 }
24  
25 int main(int argc, char* argv[])
26 {
27     int x[] = {0,0,0,0};
28  
29     bigmul(87654321, 12345678, x);
30  
31     printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);
32  
33     return 0;
34 }

答案:

n2 / base + n3 / base + n4 % base
r[2] / base

 

第七题:

补全代码,有个6*6的棋盘,预先已经放置了一部分棋子,现在要再补充棋子使得每行每列都有3个棋子

题目附带的不完整代码:

001 int N = 0;
002  
003 bool CheckStoneNum(int x[][6])
004 {
005     for(int k=0; k<6; k++)
006     {
007         int NumRow = 0;
008         int NumCol = 0;
009         for(int i=0; i<6; i++)
010         {
011             if(x[k][i]) NumRow++;
012             if(x[i][k]) NumCol++;
013         }
014         if(_____________________) return false// 填空
015  }
016     return true;
017 }
018  
019 int GetRowStoneNum(int x[][6], int r)
020 {
021     int sum = 0;
022     for(int i=0; i<6; i++) if(x[r][i]) sum++;
023     return sum;
024 }
025  

你可能感兴趣的:(C++)