• C++
  • STEMA考试 C++ 真题试卷2

  • @ 2024-2-23 18:01:35

单项选择题

第1题

执行 cout << '9'*3; 语句后,输出的结果是( )。

A. 27

B. 9*3

C. 999

D. 171

答案:D

解析:char类型与int类型的计算结果为int,9的ASCII码为57,所以最终输出171。

第2题

已定义:int a = 02023, b = 0x212; a + b 的值是( )。

A. 八进制数4771

B. 十进制数1573

C. 十进制数2553

D. 十六进制数9f9

答案:B

解析:首先a转二进制为:0100 0001 0011

b转二进制为:0010 0001 0010

求和:1100 0100 0101

转八进制:6105

转十六进制:C45转十进制:1573

第3题

执行以下代码,输出的结果是( )。

#include <iostream>
using namespace std;


int func(int x){
	if (x <= 4)
		return 2 * x - 1;
	else if (x > 7)
		return func(x - 4) + x;
	else
		return func(x + 3) + 2;
}


int main(){
	cout << func(10);
	return 0;
}

A. 26

B. 29

C. 38

D. 45

答案:C

解析:

f(10) = f(6) + 10

f(6) = f(9) + 2

f(9) = f(5) + 9

f(5) = f(8) + 2

f(8) = f(4) + 8

当 x = 4 时,返回值为 2 * 4 - 1 = 7。

f(10) = 7 + 8 + 2 + 9 + 2 + 10 = 38。

第4题

下列选项中,判断a不等于0且b不等于0的正确的条件表达式是( )。

A. !(a0 && b0)

B. !a=0 && !b=0

C. a && b

D. !((a!=0) && (b!=0))

答案:C

第5题

执行语句 int a[3][4] = {{1, 2}, {3}, {4, 5, 6, 7}}; 后,a[1][2] 和a[2][1] 的值分别为:( )。

A. 2、3

B. 0、5

C. 2、5

D. 5、0

答案:B

解析:该数组三行四列,未赋值元素的值都为0。

0 1 2 3
0 1 2 0
1 3 0
2 4 5 6 7

程序设计题

第1题 促销活动

某超市搞促销活动,活动内容:购物金额每满200元(含200元)就可以享受“满200减25”的优惠。已知小维的购物金额为N(1<N<1000000),请计算出享受优惠后他需要支付多少元。

例如:N=430,购物金额为430元时,满足2次“满200减25”的条件,所以可以减去2个25元,最后结账时需支付的金额为380元(380=430-2×25)。

输入描述:输入一个正整数N(1<N<1000000),表示购物金额(单位:元)

输出描述:输出一个正整数,表示享受优惠后需要支付的金额(单位:元)

样例输入:430

样例输出:380

第2题 相邻身高差

题目描述:

有N(4≤N≤100)名同学站成一队,已知每名同学的身高 (单位:厘米),比较该队中任意相邻两名同学的身高差距(取正值),并输出最大值。

例如:N = 8,8名同学的身高分别是151、120、144、182、160、158、147、161,相邻两名同学的身高差距依次是31、24、38、22、2、11、14,其中身高差距最大值是38。

计算相邻两数之差,求最大值,注意导入cmath库,引入abs函数。

输入描述:

第一行输入一个正整数N(4≤N≤100),表示站队的同学人数 第二行输入N个正整数(80≤正整数≤220),表示队列中学生的身高(单位:厘米),相邻两个正整数之间用一个空格隔开

输出描述:

输出一个非负整数,表示相邻两名同学身高差距的最大值

样例输入:

8

151 120 144 182 160 158 147 161

样例输出:

38

#include <iostream>
#include <cmath>
using namespace std;


int n;
int a[110];
int res = 0;


int main() {
  
  cin >> n;
  for(int i = 1; i <= n; i++){
    cin >> a[i];
    if(i >= 2)
      res = max(res, abs(a[i] - a[i - 1]));
  }  


  cout << res << endl;


  return 0;
}

第3题 九进制回文数

提示信息:

回文数:反向排列与原来一样的数就叫做回文数 。 例如,12321是回文数,1231不是回文数。

九进制数:指逢9进位的一种进位计数制,以0、1、2、3、4、5、6、7、8共九个数码表示。例如:十进制数9等于九进制数10,十进制数81等于九进制数100,以此类推。

题目描述:

给定两个正整数N和M(1≤N≤M≤5000),请计算出N到M之间(含N和M)总共有多少个数满足以下条件:

1、转换为九进制之后为回文数;

2、转换为九进制后每个数位上的数字都是奇数。

例如:

当N=90,M=120,90到120之间(含90和120)总共有2个数满足条件,为91和109。

91转换为九进制为111,是一个回文数,且每个数位上的数字都是奇数;

109转换为九进制为131,是一个回文数,且每个数位上的数字都是奇数;故输出2。

输入描述:

输入两个正整数N和M(1≤N≤M≤5000),两个正整数之间用一个空格隔开

输出描述:

输出一个整数,表示N到M之间(含N和M)总共有多少个满足条件的正整数

样例输入:90 120

样例输出:2

主要逻辑:从n到m之间进行枚举,对于每一个数,判断是否是九进制回文数,且每一位都是奇数。

#include <iostream>
#include <cstdio>
using namespace std;


int n, m;
int res = 0;


bool is_huiwen(int n){
    int a[10] = {0}, idx = 0;
    while(n){
        a[++idx] = n % 9;
        n /= 9;
    }
    
    for(int i = 1; i <= (idx + 1) / 2; i++)
        if(a[i] != a[idx - i + 1])
            return false;
    
    for(int i = 1; i <= idx; i++)
        if(a[i] % 2 == 0)
            return false;
    
    return true;
}


int main() {
	
    cin >> n >> m;
    
    for(int i = n; i <= m; i++)
        if(is_huiwen(i))
            res++;
            
	cout << res << endl;
    
	return 0;
}

第4题 收集宝石

题目描述:

聪聪在玩冒险岛游戏,为了召唤法力更强大的神龙,他必须尽可能收集更多的魔法宝石,每颗宝石都有不同的功效。不过在游戏里,几乎每一颗魔法宝石都会和另外一颗宝石相冲。相冲表示这两颗宝石不能同时拥有。例如,宝石A和宝石B相冲,那么,你可以选择两颗宝石都不收集,也可以只收集宝石A或者只收集宝石B,但不能同时拥有宝石A和宝石B。

现在给定了游戏里宝石的数量N(2≤N≤100),宝石从1到N依次编号,并给出M对(2≤M≤2000)相冲的宝石编号,请帮聪聪计算出最多能够收集到多少颗宝石。

例如: N=6,M=8时,6颗宝石的编号分别为1、2、3、4、5、6,其中有8对相冲的宝石,对应编号如下: 1 2 2 3 2 4 2 5 2 6 3 4 4 5 5 6

这表示宝石1和宝石2相冲,宝石2和宝石3、4、5、6都相冲,宝石3和宝石4相冲,宝石4和宝石5相冲,宝石5和宝石6相冲。

有三个方案收集到的宝石数量最多:(1 3 5)、(1 3 6)、(1 4 6),这些方案里,最多收集到的宝石数量都是3,所以程序输出3。

输入描述: 第一行输入两个正整数N和M(2≤N≤100,2≤M≤2000),分别表示游戏里的宝石数量和M对相冲的宝石,两个正整数之间用一个空格隔开

接下来输入M行,每行两个正整数,分别表示相冲的两颗宝石的编号,两个整数之间用一个空格隔开

输出描述:输出一个整数,表示聪聪在游戏里最多能够收集到的宝石数量

样例输入:

6 8

1 2

2 3

2 4

2 5

2 6

3 4

4 5

5 6

样例输出:

3

提示:

用邻接矩阵g存储相冲的宝石,p存储已经选择的宝石,然后深搜枚举所有情况。

#include <iostream>
#include <cstdio>
using namespace std;


const int N = 110;


int n, m;
bool g[N][N], p[N];


int res = 0;


void dfs(int u, int sum){
    
    /*
      剪枝:枚举到第u个宝石,选择宝石数为sum,即使把后面所有宝石(n-u)都选中,
        都小于之前的最大值res,就满足剪枝条件。
    */
    if(res > sum + n - u) return;
    
    if(u > n){
        res = max(res, sum);
        return;
    }
    
    bool is_conflict = false;
    for(int i = 1; i < u; i++){
        if(p[i] && g[i][u]){
            is_conflict = true;
            break;
        }
    }
    
    if(!is_conflict){
        p[u] = true;
        dfs(u + 1, sum + 1);
    }
    
    p[u] = false;
    
    dfs(u + 1, sum);
}
    
int main() {
    
    cin >> n >> m;
    
    while(m--){
        int a, b;
        cin >> a >> b;
        g[a][b] = g[b][a] = true;
    }
    
    dfs(1, 0);
    
    cout << res <<endl;


  return 0;
}

第5题 简易炸弹超人

题目描述:

有一块矩形游戏场地,场地被分成N×M的网格(4≤N≤100,4≤M≤10),其中一部分小方格是水域,另一部分小方格是陆地。

为防御敌军攻击,玩家需要在游戏场地安置炸弹:

1.炸弹只能安置在陆地上。

2.每颗炸弹爆炸后,可以波及到炸弹所在的小方格,及相邻的上、下、左、右小方格。

3.炸弹爆炸后所波及到的小方格不可以重叠。请帮助玩家计算出如何安置炸弹,可以使炸弹波及到的范围最大,输出最多可以波及到的小方格数量。

例如:N = 4,M = 4,网格中水域和陆地的情况如图1所示 image

图中,蓝色区域代表水域,绿色区域代表陆地;安置炸弹的最优方案之一如图2所示;

炸弹波及的范围如图3所示(黑色区域)。

这块4×4的矩形游戏场地最多可以波及到11个小方格,其他方案都不会优于这个结果。

输入描述:

第一行输入两个正整数N和M(4≤N≤100,4≤M≤10),分别表示网格的行数和列数,两个正整数之间以一个空格隔开

第二行开始输入N行,每行M个字符(字符只能是大写字母A或B),A表示水域,B表示陆地,字符之间以一个空格隔开

输出描述:

输出一个整数,表示最多可以波及到的小方格数量

样例输入:

4 4

B A A A

A B A B

B A B B

A B A A

样例输出:

11

解析:状态压缩DP

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;


const int N = 110, M = 1 << 10;


int n, m;
int g[N];
int f[2][M][M];
vector<int> s;


bool check(int s){
    return !(s & s >> 1 || s & s >> 2);
}


bool check2(int s){
    return s & s >> 1;
}


int count(int i, int s){
	int cnt = 0, flag = 0;
	for(int j = 0; j < m; j++){
        if(s >> j & 1){
            flag = 1;
            if(i - 1 >= 1) cnt++;
            if(i + 1 <= n) cnt++;
            if(j - 1 >= 0) cnt++;
            if(j + 1 < m) cnt++;
        }
    }
	return cnt + flag;
}




int main() {
    
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        for(int j = 0; j < m; j++){
            char ch;
            cin >> ch;
            if(ch == 'A') g[i] += 1 << j;
        }
    }
         
    for(int i = 0; i < 1 << m; i++)
        if(check(i)) s.push_back(i);
     
    for(int i = 1; i <= n + 2; i++){
        for(int j = 0; j < s.size(); j++)
            for(int k = 0; k < s.size(); k++)
                for(int u = 0; u < s.size(); u++){
                    // a当前行状态 b上一行状态 c上两行状态      
					int a = s[j], b = s[k], c = s[u];
                    if((a & b) || (a & c) || (b & c)) continue;
                    if((g[i] & a) || (g[i - 1] & b)) continue;
                    if(check2(b | c)) continue;
                    int cnt = i <= n ? count(i, a) : 0;
                    f[i & 1][j][k] = max(f[i & 1][j][k], f[i - 1 & 1][k][u] + cnt);
                    
                    
                }
    }
                        
    cout << f[n + 2 & 1][0][0] << endl;
	
	return 0;
}

0 条评论

目前还没有评论...