蓝桥青少 2021 C++中级 省赛真题(十二届)

选择题
第一题

在C++中下列哪个不属于字符型常量()。
*选择题严禁使用程序验证
A、‘a’ B、‘X2A’ C、’@ D、"F”

解析:字符型常量是用单引号,但是‘x2A’会输出A,其中x会使输出其后的最后一个字符列如:‘x2435345&’会输出&。选项中,A、B、C都是字符型常量,而D是一个字符串常量,因此不属于字符型常量,正确答案为D。
第二题

以下列变量定义不正确的是()。
*选择题严禁使用程序验证
A、int a=8,b,c; B、float c=1.233; C、int if; D、char d=‘i’;

解析:选项A、B、D都是正确的变量定义方式,而选项C中变量名使用了关键字if,是非法的,正确答案为C。
第三题

已知"int n=9;”, 则执行语句”n*=n+=n%=2;”后,n的值为()。
*选择题严禁使用程序验证
A、4 B、1 C、8 D、18

解析: 根据C++的运算符优先级和结合律,先计算取模运算,再计算加法运算,最后计算赋值运算。因此,n%=2的结果是1,n+=1后n的值为2,n*=2后n的值为4,正确答案为A。*
第四题

二进制加法11010+10110的和为()。
*选择题严禁使用程序验证
A、110000 B、11000 C、101110 D、111010

解析:二进制加法的规则与十进制加法类似,逢二进一,结果中每一位都是0或1。在本题中,从低位开始加,1+0=1,0+1=1,1+1=0进1,0+1=1,1+1=0进1,得到的结果为101000,因此正确答案为A。
第五题

C++中函数的返回值类型是由()。
*选择题严禁使用程序验证
A、调用该函数的主调用函数类型决定的
B、return语句中的表达式类型决定的
C、定义该函数所指的数据类型决定的
D、系统自动决定的

解析: C++函数的返回值类型是由函数定义时指定的,一旦确定后就不能更改。在函数定义中使用return语句返回一个值时,该值的类型应与函数返回值类型一致。因此,正确答案为C。
编程题
第一题:编程实现:字符串

题目描述:
给定一个字符串,然后将字符串倒序输出。
输入描述:
输入一个字符串S(2<S长度<100)
输出描述:
将字符串S倒序输出

输入样例:
abc

输出样例:
cba

#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	getline(cin,s);
	for(int i=s.length()-1;i>=0;i--){
		cout<<s[i];
	}
	return 0;
}

第二题:编程实现:剪绳子

题目描述:
一条绳子从中间剪一刀可以剪成两段绳子;如果对折1次,中间剪一刀可以剪出3段绳子;如果连续
对折2次,中间剪一刀可以剪出5段绳子;那么,连续对折次,中间剪一刀可以剪出多少段绳子?
通过编写程序,在给定绳子对折次数,计算出中间剪一刀后可剪出绳子的段数。

输入描述:
输入一个正整数n(2<n<20)作为绳子对折的次数
输出描述:
输出一个正整数,表示对折次后的绳子中间剪一刀可以剪出绳子的段数

输入样例:
3
输出样例:
9

解题思路:

通过观察可以发现,第一次对折后,中间剪一刀可以剪出 3 段,第二次对折后,中间剪一刀可以剪出 5 段,以此类推,可得到一个规律:每次对折后,中间剪一刀可以剪出的绳子段数会增加一倍。根据此规律,可以利用递推公式 f ( n ) = 2 n + 1 f(n) = 2^n + 1 f(n)=2n+1,其中 f ( n ) f(n) f(n) 表示对折 n n n 次后,中间剪一刀可以剪出的绳子段数。

#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin>>n;
	int a[20];
	a[0]=2;
	a[1]=3;
	a[2]=5;  
	for(int i=3;i<=n;i++){
		int b=1;
		for(int j=1;j<=i-1;j++){
			b*=2; 
		}
		a[i]=a[i-1]+b;
	}
	cout<<a[n]<<endl;
	//cout<<pow(2,n)+1; (直接输出不用递推也可以)
	return 0;
}

第三题 :编程实现:求和

提示信息:
合数指自然数中除了能被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<bits/stdc++.h>
using namespace std;
int main(){
	int n,s=0;
	cin>>n;
	for(int i=4;i<=n;i++){
		int flag=0; 
		for(int j=2;j<i;j++){
			if(i%j==0){
				flag=1;
			} 
		}
		if(flag==1){
			s+=i;
		}
	}
	cout<<s;
	return 0;
}

第四题 :编程实现:求和比较

题目描述:
小蓝在学习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(3<N<30)和M(0≤M≤500),两个正整数由一个空格隔开
输出描述:
输出一个正整数,表示1到N(包含1和N)连续的正整数数组中有多少种方案,使得拆分的两个子
数组部分和的差值等于M

输入样例:
5 1
输出样例:
3

#include<bits/stdc++.h>
using namespace std;
int n,m,s;
void dfs(int t,int s1,int s2){
  if(t>n){
      if(s1-s2==m){
      	s++;
	  }
      return;
  }
  dfs(t+1,s1+t,s2);
  dfs(t+1,s1,s2+t);
}

int main(){
  cin>>n>>m;
  dfs(1,0,0);
  cout<<s<<endl;
  return 0;
}

第五题 :编程实现:最大价值

题目描述:
一名种菜的农民伯伯,需要在给定的时间内完成种菜,现有种不同的蔬菜提供给农民伯伯选择,且
每种蔬菜种植花费的时间不同,每种蔬菜成熟后售卖的价值也不同。
要求:
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行每行输入两个正整数t1(1 < t1 < 101)和p(1 < p < 101)且用一个空格隔开,t1表
示每种蔬菜种植需要花费的时间,p表示对应蔬菜成熟后售卖的价值。
输出描述:
输出一个正整数,表示选择最优的种植方案后,蔬菜成熟后售卖的最大总价值

输入样例:
55 3
21 9
20 2
30 21
输出样例:
30

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t,m;
	cin>>t>>m;
	int a[51][2],dp[601]={};
	for(int i=0;i<m;i++){
		cin>>a[i][0]>>a[i][1];
	}
	for(int i=0;i<m;i++){
		int time=a[i][0];
		int v=a[i][1],s=0;
		for(int j=t;j>=time;j--){
			dp[j]=max(dp[j],dp[j-time]+v);
		}
	}
	cout<<dp[t];
	return 0;
}

第六题:编程实现:最短距离

题目描述:
在一个矩阵精灵王国里有两个精灵,一个叫黑精灵,一个叫白精灵。他们住在一个N*M的矩阵方格中
的不同位置,黑精灵住在矩阵方格的左上角方格里(1,1),白精灵住在矩阵方格的右下角方格里(N,M)。

在这个矩阵方格里还有一对可穿越的门,这对穿越门的位置不固定,位置可变换(穿越门不会出现在矩
阵方格左上角和右下角位置,也不会重叠出现,有且只有一对)。穿越门的功能是当进入其中一扇门的
位置后可直接穿越到另一扇门的位置。

如下图所示:

一天黑精灵要去白精灵家做客,需要穿过方格矩阵到达白精灵家,穿行矩阵方格要求:
1.每次只能走一个方格,可以向上、向下、向左、向右行走;
2.每走一个方格计为1步,但从一扇穿越门穿越到另一扇穿越门不记步数(从方格走到穿越门和从穿
越门到其他方格都计1步);
3.可借助穿越门去白精灵家(可减少行走步数)。
为了尽快到达白精灵家,请你帮助黑精灵找一条最短路线,并且计算出最短路线的步数。

例如:
给出一个3*4矩阵方格,并给出第一个穿越门的坐标位置N1,M1(2,3),,第二个穿越门的坐标位
置N2,M2(3,1),已知黑精灵初始坐标位置左上角(1,1),白精灵坐标位置右下角(N,
M)
假设用两个大写字母“D”表示矩阵方格中穿越门位置,1代表黑精灵,2代表白精灵,用数字0表示
剩余矩阵方格。
如下图所示:

按照穿行矩阵方格要求为左上角方格的黑精灵到右下角方格白精灵家找一条最短路线,计算出最短路线
的步数。

路线:从黑精灵初始位置(1,1)到正下方方格(2,1)走1步,正下方方格(2,1)到其下方穿越门(3,1)“D”走1步,然后穿越到另一扇穿越门(2,3)向正下方(3,3)走1步,最后到达白精灵家(3,4)需要走1步,故最短路线需要4步。

输入描述:
第一行输入两个以一个空格隔开的正整数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);第一个穿越门位置要在第二个穿越门前边或者上边。

输出描述:
输出一个整数,表示黑精灵去白精灵家最短路线需要走多少步(可借助穿越门,减少步数)。

输入样例:

3 4
2 3
3 1

输出样例:
4

/*
解题思路:
	理清题意后 我们会发现:
	最优方案是从距离终点较远的传送门 传送到距离终点较近的传送门。其余路线的长度就是曼哈顿
*/
#include<bits/stdc++.h>
using namespace std;
int main() {
    int n,m,n1,m1,n2,m2;
    // 输入矩阵大小和穿越门位置
    cin>>n>>m>>n1>>m1>>n2>>m2;
    int dis1=abs(n1-n)+abs(m1-m);//终点到传送门的距离 曼哈顿距离=|x1-x2|+|y1-y2|
    int dis2=abs(n2-n)+abs(m2-m);
    // 计算使用穿越门的情况下从黑精灵走到白精灵的步数
    int s=n+m-2-abs(dis1-dis2);//使用传送门对结果的影响就是缩减了一些距离
    // 输出最短步数 -2是因为使用了传送门
    cout<<s<<endl;
    return 0;
}

  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值