考题解析2021年4月蓝桥杯省赛C++中级组

Posted 青少年信息学编程竞赛与升学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了考题解析2021年4月蓝桥杯省赛C++中级组相关的知识,希望对你有一定的参考价值。

一想到你在关注我就忍不住有点紧张


# LAN QIAO #

蓝桥杯大赛是工信部人才交流中心举办的全国性专业信息技术赛事。
12年来,作为首屈一指的信息技术赛事,蓝桥杯吸引了北大清华在内的超过 1500 所院校、累计40余万名学子参赛,IBM、百度等知名企业全程参与。蓝桥杯大赛塑造了领跑全国的人才培养选拔模式,并获得了行业的深度认可。
自2016年第八届起,赛事在原有大学生数个专业编程组别的基础上增加了中小学创意编程组,简称青少组。第11届竞赛,超过4万名中小学生参加了青少组的比赛。第12届起,STEMA评测考试替代了青少组的地区选拔赛,更加全面和科学地评测学生的科技素养、逻辑思维和编程能力,给出可以跨时间地域衡量的综合评测成绩。
蓝桥杯省赛仅有在蓝桥杯STEAM测评中获奖考生才可报名参赛。
本次考试于2021年4月24日开考,当天结束,老师特意为同学们带来了真题解析,为已经参考的同学和即将参考的同学留下复习及参考资料,快来看看吧!

1

字符串(30分)

题目描述

给定一个字符串,然后将字符串倒序输出。

内存时间限

时间限制:无

内存限制:无

输入格式

输入一个字符串S(2<S长度<100)

输出格式

将字符串S倒序输出

样例输入

abc

样例输

cba

#include<iostream>

#include<string>

using namespace std;

int main()

{

    string s;

    cin>>s;

    int len=s.size(); 

    for(int i=len-1;i>=0;i--)

        cout<<s[i];

    cout<<endl;

    return 0;

}

2

剪绳子(40分)  

【题目描述】

一条绳子从中间剪一刀可以剪成两段绳子;如果对折1次,中间剪一刀可以剪出3段绳子;如果连续对折2次,中间剪一刀可以剪出5段绳子;那么,连续对折n次,中间剪一刀可以剪出多少段绳子?

通过编写程序,在给定绳子对折次数,计算出中间剪一刀后可剪出绳子的段数。

内存时间限制

时间限制:无

内存限制:无

输入格式

输入一个正整数 n(2<n<20)作为绳子对折的次数

输出格式

输出一个正整数,表示对折n次后的绳子中间剪一刀可以剪出绳子的段数

样例输

2

样例输出

5

#include<iostream>

using namespace std;

int main()

{

    int n;

    cin>>n;

    int ans=1;

    for(int i=1;i<=n;i++)

        ans*=2;

    ans+=1;

    cout<<ans;

    return 0;

}


3

合数求和(50分)

【题目描述】

合数指自然数中除了能被1和它本身整除外,还能被其他数(0除外)整除的数。最小的合数是4。

如:合数4既可以被1和4整除,还能被2整除。

给定一个正整数N,计算出4到N之间所有合数的和。

例如:N等于7,其中4到N之间合数有4、6,所有合数和等于10(4+6=10)

内存时间限制

时间限制:无

内存限制:无

输入格式

输入一个正整数N(4<N<101)

输出格式

输出一个整数,表示4到N之间(包含4和N)所有合数的和

样例输入

7

样例输出

10

#include<iostream>

#include<cmath>

using namespace std;

bool isPrime(int n)

{

int i;

    for(i=2;i<=sqrt(n);i++)

    {

        if(n%i==0)

break;

    }

    return i>sqrt(n);

}

int main()

{

    int n;

    cin>>n;

    int sum=0;

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

    {

        if (isPrime(i)==false)

            sum+=i;

    }

    cout<<sum<<endl;

    return 0;

}

4

求和比较(总分60分)

【题目描述】

小蓝在学习C++数组时,突发奇想想知道如果将一个连续的正整数数组拆分成两个子数组,然后对拆分出的两个子数组求和并做差,且差值正好等于一个固定的正整数,像这样同一连续的正整数数组拆分方案有多少种。
我们一起帮助小蓝设计一下规则:

第一给出两个正整数N和M;
第二从1到N组成一个连续正整数数组A(A={1,2,3,4……N});
第三将数组A拆分成两个子数组A1、A2(1.两个子数组中不能出现相同的数;2.子数组中的数字可以是连续的也可以是不连续的;3.拆分出的两组子数组的元素个数可以不同,但总数量等于A数组元素个数);
第四对A1、A2两个子数组分别求和;
第五对A1、A2两个子数组的和做差(大的数字减去小的数字);
第六如果差值正好等于固定值M,则判定此拆分方案成立。

如:N=5,M=1,连续正整数数组A={1, 2, 3, 4, 5}。
符合条件的拆分方案有3种:

A1={1, 2, 4}, A2={3, 5}, 其中A1的和为7,A2的和为8,和的差值等于1
A1={1, 3, 4}, A2={2, 5}, 其中A1的和为8,A2的和为7,和的差值等于1
A1={3, 4}, A2={1, 2, 5}, 其中A1的和为7,A2的和为8,和的差值等于1

【内存时间限制】

时间限制:无

内存限制:无

【输入格式】

输入两个正整数N和M(3<N<30,0<=M<=500)

【输出格式】

输出拆分方案数。

【样例输入】

5 1

【样例输出】

3

#include<iostream>

#include<algorithm>

using namespace std;

int dp[35][550];

int main()

{

    int n,m;

    cin>>n>>m;

    int sum=0;

    dp[0][0]=1;

    for(int i=1;i<=n;i++)

    {

        for(int j=0;j<=(i+1)*i/2;j++)

            dp[i][j]=dp[i-1][j+i]+dp[i-1][abs(j-i)];

    }

    if(m==0)

        cout<<dp[n][m]/2<<endl;

    else

        cout<<dp[n][m]<<endl;

    return 0;

}

5

最大价值(总分80分)

【题目描述】

一名种菜的农民伯伯。需要在给定的时间内完成种菜,现有m种不同的蔬菜提供给农民伯伯选择,且每种蔬菜种植花费的时间不同,每种蔬菜成熟后售卖的价值也不同。

要求:
1.在限定的总时间内进行蔬菜种植,并且种植蔬菜的种类不能超出限制的数量;
2.选择最优的种植方案使得蔬菜成熟后售卖的总价值最大(可选择不同的蔬菜种植)。

例如:
给定的总时间限制为55,种植蔬菜的种类限制为3;
3种蔬菜,种菜的花费时间及售卖价格分别为:第一种21和9,第二种20和2,第三种30和21。
最优的种植方案是选择种植第一种和第三种,两种蔬菜种植总时间30+21,未超过总时间限制55。所种植蔬菜为两种,也未超过种类限制的3种。最大总价值为9+21=30,这个方案是最优的。

【内存时间限制】

时间限制:无

内存限制:无

【输入格式】

第一行输入两个正整数t(1<=t<=600)和m(1<=m<=50),用一个空格隔开,t代表种菜总时间限制,m代表最多可种植蔬菜种类的限制;
接下来的m行每行输入两个正整数t1(1<t1<101)和p(1<p<101)且用一个空格隔开,t1表示每种蔬菜种植需要花费的时间,p表示对应蔬菜成熟后售卖的价值。

【输出格式】

输出一个正整数,表示选择最优的种植方案后,蔬菜成熟后售卖的最大总价值。

【样例输入】

53 3

21 9

20 2

30 21

【样例输出】

30

#include<iostream>

#include<algorithm>

using namespace std;

int w[55],v[55];

int dp[55][605];

int main()

{

    int t,m;

    cin>>t>>m;

    for(int i=1;i<=m;i++)

        cin>>w[i]>>v[i];

    for(int i=1;i<=m;i++)

    {

        for(int j=1;j<=t;j++)

        {

            if(j>=w[i])

                dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

            else

                dp[i][j]=dp[i-1][j];

        }

    }

    cout<<dp[m][t]<<endl;

    return 0;

}

6

黑精灵与白精灵(总分100分)

【题目描述】

【考题解析】2021年4月蓝桥杯省赛C++中级组

如下图所示:

【考题解析】2021年4月蓝桥杯省赛C++中级组


【考题解析】2021年4月蓝桥杯省赛C++中级组

如下图所示:

【考题解析】2021年4月蓝桥杯省赛C++中级组


【考题解析】2021年4月蓝桥杯省赛C++中级组

【内存时间限制】

时间限制:无

内存限制:无

【输入格式】

第一行输入两个以一个空格隔开的正整数N(2<N<101),M(2<M<101),分别表示N行M列的方格矩阵;
接下来第二行输入两个以一个空格隔开的正整数:N1(N1<=N),M1(M1<=M),代表第一个穿越门位于第N1行第M1列;
接下来第三行输入两个以一个空格隔开的正整数:N2(N2<=N),M2(M2<=M),代表第二个穿越门位于第N2行第M2列;
注意:两个穿越门位置不能重叠,即不能同时满足N1=N2和M1=M2;两个穿越门位置也不能位于左上角(1,1)和右下角(M,N);第一个穿越门位置要在第二个穿越门前边或者上边。

【输出格式】

输出一个整数,表示黑精灵去白精灵家最短路线需要走多少步(可借助穿越门,减少步数),如果没有能到达白精灵家的路线或者其他情况统一输出数字“0”。

【样例输入】

3 4

2 3

3 1

【样例输出】

4

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

    int n,m;

    cin>>n>>m;

    int n1,m1,n2,m2;

    cin>>n1>>m1>>n2>>m2;

    int ans1=(n1+m1-2)+(n-n2+m-m2);

    int ans2=(n2+m2-2)+(n-n1+m-m1);

    cout<<min(ans1, ans2)<<endl;

    return 0;



NEWS