第七届蓝桥杯CC++B组题解.docx

上传人:b****8 文档编号:10881013 上传时间:2023-02-23 格式:DOCX 页数:29 大小:26.10KB
下载 相关 举报
第七届蓝桥杯CC++B组题解.docx_第1页
第1页 / 共29页
第七届蓝桥杯CC++B组题解.docx_第2页
第2页 / 共29页
第七届蓝桥杯CC++B组题解.docx_第3页
第3页 / 共29页
第七届蓝桥杯CC++B组题解.docx_第4页
第4页 / 共29页
第七届蓝桥杯CC++B组题解.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

第七届蓝桥杯CC++B组题解.docx

《第七届蓝桥杯CC++B组题解.docx》由会员分享,可在线阅读,更多相关《第七届蓝桥杯CC++B组题解.docx(29页珍藏版)》请在冰豆网上搜索。

第七届蓝桥杯CC++B组题解.docx

第七届蓝桥杯CC++B组题解

第一题

煤球数目

有一堆煤球,堆成三角棱锥形。

具体:

第一层放1个,

第二层3个(排列成三角形),

第三层6个(排列成三角形),

第四层10个(排列成三角形),

....

如果一共有100层,共有多少个煤球?

请填表示煤球总数目的数字。

注意:

你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

这道题坑死了,第一次看堆成三角棱锥形,草稿本画半天都没画出个三角棱锥。

后来单独看每句话才知道每层一个三角形叠起来就是三角棱锥。

我去。

看懂题目这个题目就很简单了,每层的个数是上层的个数加上层数,意思就是An=An-1+n,然而题目是求的前100层一共多少煤球。

所以是Sn.代码双重for循环就出来了。

答案是:

171700

1.#include  

2.int main()  

3.{  

4.    int a[101] ={0};  

5.    for(int i = 1 ; i < 101 ; i ++)  

6.        a[i] = a[i-1] + i;  

7.    int ans = 0;  

8.    for(int j = 1 ; j < 101 ; j ++)  

9.        ans += a[j];  

10.    printf("%d\n",ans);  

11.    return 0;  

12.}  

第二题:

生日蜡烛

某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。

现在算起来,他一共吹熄了236根蜡烛。

请问,他从多少岁开始过生日party的?

请填写他开始过生日party的年龄数。

注意:

你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

呵呵,水题,但是出题人不严谨啊!

怎么就不能考虑万一他今年236岁呢....好了不说了强迫症犯了。

蓝桥杯这种不像acm的题目的,能暴力直接暴力。

不用想太多。

直接从1~236枚举start,end分别表示他开始过生日的年龄和今年的年龄,然后计算之间吹蜡烛的总和如果等于236就输出start,end. 答案是:

26

1.#include  

2.int main()  

3.{  

4.    int start,end;  

5.    for(start = 1 ; start < 236 ; start ++)  

6.    {  

7.        for( end = start ; end < 236 ; end ++ )  

8.        {  

9.            int sum = 0;  

10.            for(int i = start; i <= end; i ++)  

11.                sum += i;  

12.            if( sum == 236)  

13.            {  

14.                printf("start :

 %d end :

 %d\n",start,end);  

15.            }  

16.        }  

17.    }  

18.    return 0;  

19.}  

第三题:

凑算式

    B   DEF

A+—+-———=10

    C   GHI

(如果显示有问题,可以参见【图1.jpg】)

这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。

比如:

6+8/3+952/714就是一种解法,

5+3/1+972/486是另一种解法。

这个算式一共有多少种解法?

注意:

你提交应该是个整数,不要填写任何多余的内容或说明性文字。

这个题不多说了,直接暴力生成9的全排列然后去验证等式是否成立,只是验证的时候如果防止精度问题可以通分把除法变成乘法。

答案是:

29

1.#include  

2.int ans = 0;  

3.int num[10];  

4.bool visit[10];  

5.void Solve()  

6.{  

7.    double sum = num[0] + (double)num[1] / num[2] + (double)(num[3]*100+num[4]*10+num[5])/(num[6]*100+num[7]*10+num[8]);  

8.    if(sum == 10)  

9.    {  

10.        ans ++;  

11.    }  

12.}  

13.void dfs(int index)  

14.{  

15.    if(index == 9)  

16.    {  

17.        Solve();  

18.        return ;  

19.    }  

20.    for(int i = 1 ; i < 10 ; i ++)  

21.    {  

22.        if(!

visit[i])  

23.        {  

24.            visit[i] = true;  

25.            num[index] = i;  

26.            dfs(index+1);  

27.            visit[i] = false;  

28.        }  

29.    }  

30.}  

31.int main()  

32.{  

33.    dfs(0);  

34.    printf("%d\n",ans);  

35.    return 0;  

36.}  

第四题:

快速排序

排序在各种场合经常被用到。

快速排序是十分常用的高效率的算法。

其思想是:

先选一个“标尺”,

用它把整个队列过一遍筛子,

以保证:

其左边的元素都不大于它,其右边的元素都不小于它。

这样,排序问题就被分割为两个子区间。

再分别对子区间排序就可以了。

下面的代码是一种实现,请分析并填写划线部分缺少的代码。

#include

voidswap(inta[],inti,intj)

{

intt=a[i];

a[i]=a[j];

a[j]=t;

}

intpartition(inta[],intp,intr)

{

inti=p;

intj=r+1;

intx=a[p];

while

(1){

while(i

while(a[--j]>x);

if(i>=j)break;

swap(a,i,j);

}

______________________;

returnj;

}

voidquicksort(inta[],intp,intr)

{

if(p

intq=partition(a,p,r);

quicksort(a,p,q-1);

quicksort(a,q+1,r);

}

}

intmain()

{

inti;

inta[]={5,13,6,24,2,8,19,27,6,12,1,17};

intN=12;

quicksort(a,0,N-1);

for(i=0;i

printf("\n");

return0;

}

注意:

只填写缺少的内容,不要书写任何题面已有代码或说明性文字。

这个题目如果接触过快排,了解过快速排序的原理的应该是送分题目,只不过快排单步(就是将一堆数按照某个数作为基准数分成左右两堆)这个实现方式有几种代码表现。

在这里答案是swap(a,p,j).

第五题:

抽签

X星球要派出一个5人组成的观察团前往W星。

其中:

A国最多可以派出4人。

B国最多可以派出2人。

C国最多可以派出2人。

....

那么最终派往W星的观察团会有多少种国别的不同组合呢?

下面的程序解决了这个问题。

数组a[]中既是每个国家可以派出的最多的名额。

程序执行结果为:

DEFFF

CEFFF

CDFFF

CDEFF

CCFFF

CCEFF

CCDFF

CCDEF

BEFFF

BDFFF

BDEFF

BCFFF

BCEFF

BCDFF

BCDEF

....

(以下省略,总共101行)

#include

#defineN6

#defineM5

#defineBUF1024

voidf(inta[],intk,intm,charb[])

{

inti,j;

if(k==N){ 

b[M]=0;

if(m==0)printf("%s\n",b);

return;

}

for(i=0;i<=a[k];i++){

for(j=0;j

______________________;//填空位置

}

}

intmain()

{

inta[N]={4,2,2,1,1,3};

charb[BUF];

f(a,0,M,b);

return0;

}

仔细阅读代码,填写划线部分缺少的内容。

注意:

不要填写任何已有内容或说明性文字。

这个题目是这样的,对于f(inta[],intk,intm,charb[]).a[]是每个国家的最多指派人数,k表示当前是哪个国家,m表示还需要派送几个人(可以为负数).b表示已经派送的人的字符串。

所以这个题目在递归中间的的第一个循环表示从0~a[i]中让i国选择指派人数,内循环只是向b[]记录的过程。

所以答案是f(a,k+1,m-i,b).   因为这里I=j.应该 f(a,k+1,m-j,b)也可以。

第六题:

方格填数

如下的10个格子

(如果显示有问题,也可以参看【图1.jpg】)

填入0~9的数字。

要求:

连续的两个数字不能相邻。

(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

请填写表示方案数目的整数。

注意:

你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

这个题目题目有点表述不明,不知道0~9可不可以重复使用。

我当时做的时候是当作不可以重复使用来处理的。

那么这里我就先当作不可重复使用来讲解。

这里题目还是一样先往里面填数。

用生成排列的形式。

填写完了之后再判断是否可行。

答案是:

1580

1.#include   

2.#include   

3.int flag[3][4]; //表示哪些可以填数  

4.int mpt[3][4]; //填数  

5.bool visit[10];  

6.int ans = 0;  

7.void init()   //初始化  

8.{  

9.    int i,j;  

10.    for(i = 0 ; i < 3 ; i ++)  

11.        for(j = 0 ; j < 4 ; j ++)  

12.            flag[i][j] = 1;  

13.    flag[0][0] = 0;  

14.    flag[2][3] = 0;  

15.}  

16.void Solve()  

17.{  

18.    int dir[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1};  

19.    int book = true;  

20.    for(int i = 0 ; i < 3 ; i ++)  

21.    {  

22.        for(int j = 0 ; j < 4; j ++)  

23.        {  

24.            //判断每个数周围是否满足  

25.            if(flag[i][j] == 0)continue;  

26.            for( int k = 0 ; k < 8 ; k ++)  

27.            {  

28.                int x,y;  

29.                x = i + dir[k][0];  

30.                y = j + dir[k][1];  

31.                if(x < 0 || x >= 3 || y < 0 || y >= 4 || flag[x][y] == 0) continue;  

32.                if(abs(mpt[x][y] - mpt[i][j]) == 1)  book = false;  

33.            }  

34.        }  

35.    }  

36.    if(book) ans ++;  

37.}  

38.void dfs(int index)  

39.{  

40.    int x,y;  

41.    x = index / 4;  

42.    y = index % 4;  

43.    if( x == 3)  

44.    {  

45.        Solve();  

46.        return;  

47.    }  

48.    if(flag[x][y])  

49.    {  

50.        for(int i = 0 ; i < 10 ; i ++)  

51.        {  

52.            if(!

visit[i])  

53.            {  

54.                visit[i] = true;  

55.                mpt[x][y] = i;  

56.                dfs(index+1);  

57.                visit[i] = false;  

58.            }  

59.        }  

60.    }  

61.    else  

62.    {  

63.        dfs(index+1);  

64.    }  

65.}  

66.int main()  

67.{  

68.    init();  

69.    dfs(0);  

70.    printf("%d\n",ans);  

71.    return 0;  

72.}  

第七题:

剪邮票

如【图1】,有12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的。

(仅仅连接一个角不算相连)

比如,【图2】,【图3】中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。

注意:

你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

其实这个题目还是可前面的一样,先生成,再判断是否可行。

这里我们可以先用搜索从12个数里面将所有5个数的组合找出来。

然后再用深搜判断这五个是否连在一起。

答案是:

116

1.#include   

2.#include   

3.int mpt[3][4];  

4.int mpt_visit[3][4];  

5.int num[6];   

6.int have[13];  

7.int visit[13];  

8.int ans = 0;  

9.int Count = 0;  

10.void init()  

11.{  

12.    int k = 1;  

13.    for(int i = 0 ; i < 3 ; i ++)  

14.        for(int j = 0 ; j < 4 ; j ++)  

15.        {  

16.            mpt[i][j] = k;  

17.            k ++;  

18.        }  

19.}  

20.int dir[4][2] = {0,1,0,-1,-1,0,1,0};  

21.//判断五个数是否能连在一起  

22.void dfs_find(int x,int y)  

23.{  

24.    for(int i = 0 ; i < 4 ; i++)  

25.    {  

26.        int tx,ty;  

27.        tx = x + dir[i][0];  

28.        ty = y + dir[i][1];  

29.        if(tx < 0 || tx >= 3 || ty < 0 || ty >= 4) continue;  

30.        if(have[mpt[tx][ty]] == 0 || mpt_visit[tx][ty])continue;  

31.        mpt_visit[tx][ty] = 1;  

32.        Count ++;  

33.        dfs_find(tx,ty);  

34.    }  

35.}  

36.void Solve()  

37.{  

38.    int i;  

39.    memset(have,0,sizeof(have));  

40.    memset(mpt_visit,0,sizeof(mpt_visit));  

41.    for(i = 1; i < 6 ; i ++) have[num[i]] = 1;  

42.    for(i = 0 ; i < 12 ; i ++)  

43.    {  

44.        int x,y;  

45.        x = i / 4;  

46.        y = i % 4;  

47.        if(have[mpt[x][y]])  

48.        {  

49.            Count = 1;  

50.            mpt_visit[x][y] =1;  

51.            dfs_find(x,y);  

52.            break;  

53.        }  

54.    }  

55.    if(Count == 5)  

56.    {  

57.        ans ++;  

58.    }  

59.}  

60.//创建5个数的组合  

61.void dfs_creat(int index)  

62.{  

63.    if(index == 6)  

64.    {  

65.        Solve();  

66.        return;  

67.    }  

68.    for(int i = num[index-1] + 1; i < 13 ; i ++)  

69.    {  

70.        if(!

visit[i])  

71.        {  

72.            visit[i] = true;  

73.            num[index] = i;  

74.            dfs_creat(index+1);  

75.            visit[i] = false;  

76.        }  

77.    }  

78.}  

79.int main()  

80.{  

81.    init();  

82.    dfs_creat

(1);  

83.    printf("%d\n",ans);  

84.    return 0;  

85.}  

第八题:

四平方和

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多4个正整数的平方和。

如果把0包括进去,就正好可以表示为4个数的平方和。

比如:

5=0^2+0^2+1^2+2^2

7=1^2+1^2+1^2+2^2

(^符号表示乘方的意思)

对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对4个数排序:

0<=a<=b<=c<=d

并对所有的可能表示法按a,b,c,d为联合主键升序排列,最后输出第一个表示法

程序输入为一个正整数N(N<5000000)

要求输出4个非负整数,按从小到大排序,中间用空格分开

例如,输入:

5

则程序应该输出:

0012

再例如,输入:

12

则程序应该输出:

0222

再例如,输入:

773535

则程序应该输出:

11267838

资源约定:

峰值内存消耗<256M

CPU消耗<3000ms

请严格按要求输出,不要画蛇添足地打印类似:

“请您输入...”的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意:

main函数需要返回0

注意:

只使用ANSIC/ANSIC++标准,不要调用依赖于编译环境或操作系统的特殊函数。

注意:

所有依赖的函数必须明确地在源文件中#include,不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

这个题目很水也是搜索能做的。

但是有点技巧,这里我贡献两个方法给大家参考。

方法一:

O(n^3/2).先暴力枚举前三个数然后做减法判断差是否为一个完全平方数即可。

当然虽然这个题目是n^3/2看数据貌似过不了。

但是貌似我找了几组数据都能秒出结果。

应该是绝大多数最外层循环都不会太多。

1.#include   

2.#include   

3.int main()  

4.{  

5.    int n;  

6.    int flag = false;  

7. 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1