龙空技术网

十四届蓝桥杯大赛青少年C++组STEMA选拔赛试题真题及解析

黑猫编程 558

前言:

当前兄弟们对“dp状态压缩”大体比较讲究,咱们都需要知道一些“dp状态压缩”的相关内容。那么小编在网摘上汇集了一些对于“dp状态压缩””的相关知识,希望大家能喜欢,你们一起来学习一下吧!

单项选择题

第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. !(a==0 && b==0)

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。

程序设计题

第1题 促销活动

int n;cin >> n;cout << n - n / 200 * 25 << endl;

第2题 相邻身高差

#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题 九进制回文数

主要逻辑:从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题 收集宝石

用邻接矩阵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题 简易炸弹超人

解析:状态压缩DP

首先考虑如何安置炸弹合法,即一个炸弹安置后,其周围位置不能再安置炸弹。

如果炸弹安置在红色位置,那么周围4个绿色区域都会受到波及,不能再安置炸弹。而且炸弹爆炸后不能波及到同一个区域,因此黄色部分也不能安置炸弹。

炸弹安置要求:

只能在陆地上安置炸弹,不能在水域上安置炸弹;某一行状态中不能有相邻的两个炸弹间隔小于2;相邻三行,i、i-1、i-2不冲突;当前位置与其左上、右上两个位置不冲突。

g[i]存储第i行水域情况。

第i行状态为s,二进制中1对应方格安置炸弹,0对应方格中不安置炸弹。

#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;}

标签: #dp状态压缩 #蓝桥杯历年c语言试题和答案 #c45算法实例