2017第八届蓝桥杯C/C++ B组省赛题解

时间:2022-09-10 11:46:39

 第一参加蓝桥杯,感触颇多,总之付出和收获是成比例的,所以想要比别人收获更多,就要比别人付出更多

(1)

标题: 购物单

小明刚刚找到工作,老板人很好,只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦,但又不好推辞。

这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折优惠的。

小明也有个怪癖,不到万不得已,从不刷卡,直接现金搞定。

现在小明很心烦,请你帮他计算一下,需要从取款机上取多少现金,才能搞定这次购物。

取款机只能提供100元面额的纸币。小明想尽可能少取些现金,够用就行了。

你的任务是计算出,小明最少需要取多少现金。

以下是让人头疼的购物单,为了保护隐私,物品名称被隐藏了。

--------------------

****     180.90       88折

****      10.25       65折

****      56.14        9折

****     104.65        9折

****     100.30       88折

****     297.15       半价

****      26.75       65折

****     130.62       半价

****     240.28       58折

****     270.62        8折

****     115.87       88折

****     247.34       95折

****      73.21        9折

****     101.00       半价

****      79.54       半价

****     278.44        7折

****     199.26       半价

****      12.97        9折

****     166.30       78折

****     125.50       58折

****      84.98        9折

****     113.35       68折

****     166.57       半价

****      42.56        9折

****      81.90       95折

****     131.78        8折

****     255.89       78折

****     109.17        9折

****     146.69       68折

****     139.33       65折

****     141.16       78折

****     154.74        8折

****      59.42        8折

****      85.44       68折

****     293.70       88折

****     261.79       65折

****      11.30       88折

****     268.27       58折

****     128.29       88折

****     251.03        8折

****     208.39       75折

****     128.88       75折

****      62.06        9折

****     225.87       75折

****      12.89       75折

****      34.28       75折

****      62.16       58折

****     129.12       半价

****     218.37       半价

****     289.69       8折

--------------------

需要说明的是,88折指的是按标价的88%计算,而8折是按80%计算,余者类推。

特别地,半价是按50%计算。

请提交小明要从取款机上提取的金额,单位是元。

答案是一个整数,类似4300的样子,结尾必然是00,不要填写任何多余的内容。

本题用excel 做起来相对容易,所以答案5200

180.9

0.88

159.192

10.25

0.65

6.6625

56.14

0.9

50.526

104.65

0.9

94.185

100.3

0.88

88.264

297.15

0.5

148.575

26.75

0.65

17.3875

130.62

0.5

65.31

240.28

0.58

139.3624

270.62

0.8

216.496

115.87

0.88

101.9656

247.34

0.95

234.973

73.21

0.9

65.889

101

0.5

50.5

79.54

0.5

39.77

278.44

0.7

194.908

199.26

0.5

99.63

12.97

0.9

11.673

166.3

0.78

129.714

125.5

0.58

72.79

84.98

0.9

76.482

113.35

0.68

77.078

166.57

0.5

83.285

42.56

0.9

38.304

81.9

0.95

77.805

131.78

0.8

105.424

255.89

0.78

199.5942

109.17

0.9

98.253

146.69

0.68

99.7492

139.33

0.65

90.5645

141.16

0.78

110.1048

154.74

0.8

123.792

59.42

0.8

47.536

85.44

0.68

58.0992

293.7

0.88

258.456

261.79

0.65

170.1635

11.3

0.88

9.944

268.27

0.58

155.5966

128.29

0.88

112.8952

251.03

0.8

200.824

208.39

0.75

156.2925

128.88

0.75

96.66

62.06

0.9

55.854

225.87

0.75

169.4025

12.89

0.75

9.6675

34.28

0.75

25.71

62.16

0.58

36.0528

129.12

0.5

64.56

218.37

0.5

109.185

289.69

0.8

231.752

 

 

5136.8595

 

(2)

标题:等差素数列

 

2,3,5,7,11,13,....是素数序列。

类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列。

上边的数列公差为30,长度为6。

2004年,格林与华人陶哲轩合作证明了:存在任意长度的素数等差数列。这是数论领域一项惊人的成果!

有这一理论为基础,请你借助手中的计算机,满怀信心地搜索:

长度为10的等差素数列,其公差最小值是多少?

注意:需要提交的是一个整数,不要填写任何多余的内容和说明文字。

#include<stdio.h>

#include<math.h>

int main()

{

int x,y,max,i,j,d,d1,k,k1,s;

int a[5000];

int flag ;

scanf("%d %d",&x,&y);

if(x%2==0)

x++;

for(i=x;i<=y;i=i+2)

{

for(flag=0,j=3;j<=sqrt(i);j+=2)

if(i%j==0)

{

flag=1;

break;

}

if(flag==0)

a[i]=1;

}

max=0;

for(d=2;d<=(y-x)/2;d+=2)

for(k=x;k<=y-2*d;k=k+2)

{

if(a[k]!=1)

continue;

j=k;s=0;

while(a[j]==1)

{

j=j+d;

s++;

}

if(s>max)

{

max=s;

k1=k;

d1=d;

}

}

if(max>2)

{

printf(" %d\n",max);

for(j=0;j<=max-1;j++)

printf(" %d",k1+j*d1);

}

else

printf("煤油找到");

}

记得自己之前写过在一个范围内输出等差素数的程序,所以写起来相对容易,所以机会都是留给有准备的人。多谢多练。

(3)

X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。

每块金属原料的外形、尺寸完全一致,但重量不同。

金属材料被严格地堆放成金字塔形。

这道题目,自己没用写出来,回来看了别人的代码。

根据a[i+1][j]+=a[i][j]/2;a[i+1][j+1]+=a[i][j]计算。

 #include<stdio.h>

  #include<string.h>

  #include<ctype.h>

  #include<math.h>

   int main ()

  {

      double line[60][60];

      double n,m;

     int i,j;

     memset(line,0,sizeof(line));

     for(i=1;i<=29;i++){

         for(j=1;j<=i;j++){

             scanf("%lf",&line[i][j]);

         }

     }

     for(i=1;i<=29;i++){

         for(j=1;j<=i;j++){

             line[i+1][j]+=line[i][j]/2;

             line[i+1][j+1]+=line[i][j]/2;

         }

     }

      n=m=line[30][1];

     for(i=1;i<=30;i++){

         if(n<line[30][i])

             n=line[30][i];

         if(m>line[30][i])

             m=line[30][i];

     }

     printf("n=m== %lf %lf\n",n,m);

    printf("%lf\n",n*2086458231/m);

     return 0;

 }

(4)标题:方格分割

6x6的方格,沿着格子的边线剪开成两部分。

要求这两部分的形状完全相同。

如图:p1.png, p2.png, p3.png 就是可行的分割法。

 

试计算:

包括这3种分法在内,一共有多少种不同的分割方法。

注意:旋转对称的属于同一种分割法。

 

请提交该整数,不要填写任何多余的内容或说明文字。

  

开始看到这题的时候很开心,因为之前蓝桥杯有这样类似的题目,是用深度优先搜索做的,但是我写着就发现不是一回事,还又浪费了我的时间,最后还是没有写出来,一个菜鸟不断地接受现实的洗礼。

别人家的c++代码

#include <algorithm>

#include <string.h>

#include <iostream>

#include <stdio.h>

#include <string>

#include <vector>

#include <queue>

#include <map>

#include <set>

using namespace std;

const int N = 6;

int ans = 0;

int mpt[N+1][N+1];

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

void dfs(int x,int y)

{

    if(x == 0 || y == 0 || x == N || y == N){

        ans ++;

        return;

    }

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

    {

        int tx = x + dir[i][0];

        int ty = y + dir[i][1];

        if(mpt[tx][ty])continue;

        mpt[tx][ty] = 1;

        mpt[N-tx][N-ty] = 1;

        dfs(tx,ty);

        mpt[tx][ty] = 0;

        mpt[N-tx][N-ty] = 0;

    }

}

int main()

{

    mpt[N/2][N/2] = 1;

    dfs(N/2,N/2);

    printf("%d\n",ans/4);

    return 0;

}

(5)

标题:取数位

求1个整数的第k位数字有很多种方法。

以下的方法就是一种。

// 求x用10进制表示时的数位长度

int len(int x){

    if(x<10) return 1;

    return len(x/10)+1;

}

 

// 取x的第k位数字

int f(int x, int k){

    if(len(x)-k==0) return x%10;

    return _____________________;  //填空

}

int main()

{ int x = 23574;

    printf("%d\n", f(x,3));

    return 0;

}

对于题目中的测试数据,应该打印5。

 

请仔细分析源码,并补充划线部分所缺少的代码。

 

注意:只提交缺失的代码,不要填写任何已有内容或说明性的文字。

递归,很简单的一题

答案:f(x/10,k)

 

(6)

标题:最大公共子串

最大公共子串长度问题就是:

求两个串的所有子串中能够匹配上的最大长度是多少。

比如:"abcdkkk" 和 "baabcdadabc",

可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。

下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。

请分析该解法的思路,并补全划线部分缺失的代码。

#include <stdio.h>

#include <string.h>

 

#define N 256

int f(const char* s1, const char* s2)

{

    int a[N][N];

    int len1 = strlen(s1);

    int len2 = strlen(s2);

    int i,j;

 

    memset(a,0,sizeof(int)*N*N);

    int max = 0;

    for(i=1; i<=len1; i++){

        for(j=1; j<=len2; j++){

            if(s1[i-1]==s2[j-1]) {

                a[i][j] = __________________________;  //填空

                if(a[i][j] > max) max = a[i][j];

            }

        }

    }

 

    return max;

}

 

int main()

{

    printf("%d\n", f("abcdkkk", "baabcdadabc"));

    return 0;

}

 

注意:只提交缺少的代码,不要提交已有的代码和符号。也不要提交说明性文字。

答案:a[i-1][j-1]+1

 大题明天继续。