第十六届蓝桥杯大赛软件赛省赛 C/C++ 大学B组 [京津冀]

由于官方没有公布题目的数据, 所以代码仅供参考

  1. 密密摆放

题目链接:P12337 [蓝桥杯 2025 省 AB/Python B 第二场] 密密摆放 - 洛谷

题目描述

小蓝有一个大箱子,内部的长宽高分别是 200、250、240(单位:毫米),他要用这个大箱子来放一些同样大小的小盒子,小盒子的外部长宽高分别是 30、40、50(单位:毫米)。小盒子允许从各个方向旋转(包括可以平放和倒放)。

请问小蓝最多可以在一个大箱子里面放多少个小盒子。

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int solve(int i,int j, int k){
    return i*j*k;
}
int main() {
    int ans=solve(200,250,240)/solve(30,40,50);
    cout<<ans<<endl;
    return 0;
}
  1. 脉冲强度之和

题目描述

在蓝桥电子工坊,工程师小蓝正在设计一款智能脉冲生成器,用于驱动一种新型设备。该设备的运行依赖于特定的脉冲强度,用正整数 p 表示,其必须满足以下三个条件:

可由连续 10 个正整数之和组成:即存在一个正整数 k,使得脉冲强度 p=k+(k+1)+(k+2)+⋯+(k+9)。

各个数位上的数字都相同:例如 1111、22222、333333 等。

数值不超过 20255202:即 1≤p≤20255202。

通过计算所有符合条件的脉冲强度之和,小蓝能够优化设备运行模式。对此,请帮助他计算这一总和。
解题思路:

  1. p=k+(k+1)+(k+2)+⋯+(k+9) => p=(k+k+9)*10/2=10*k+45

  2. 解 p=10*k+45, 看k有没有解, 就能验证条件1了

  3. 接着验证p的每一位是否相等

  4. 按顺序枚举p, 把所有符合条件的p累加起来

代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int maxP=20255202;
bool solve(long long p){
    string s=to_string(p); bool f=false;
    for(char c:s){
        if(c!=s[0]){
            f=true;
            break;
        }
    }
    return f;
}
int main(){
    long long ans=0;
    for(long long k=1;;k++){
        long long p=10*k+45; 
        if (p > maxP) break;
        if(!solve(p)) ans+=p;
         
    }
    cout<<ans<<endl;
    return 0;
}
  1. 25 之和

题目描述

小蓝最近对求和很着迷,给定一个正整数 n,他想求从 n 开始的连续 25 个整数的和,即 n+(n+1)+(n+2)+⋯+(n+24),请帮帮他吧。

输入格式

输入一行包含一个正整数 n。

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; cin>>n;
    long long ans =25*(n+(n+24))/2; 
    cout<<ans<<endl;
    return 0;
}
  1. 旗帜

小蓝要画一个 LANQIAO 图形,并把这个图形做成一个旗帜。图形的形状为一个 h×w 的矩形,其中 h 表示图形的高,w 表示图形的宽。当 h=5,w=10 时,图形如下所示:

LANQIAOLAN

ANQIAOLANQ

NQIAOLANQI

QIAOLANQIA

IAOLANQIAO

图形的规律是:第一行用 LANQIAO 重复填入,第二行开始,每行向左移动一个字符,用 LANQIAO 重复填入。

小蓝需要把图形中的每个字母都剪出来,以粘贴到旗帜上,他想知道,给定图形的高和宽,图形中有多少个 A

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
    int h, w;
    cin >> h >> w;
    string s = "LANQIAO";
    int ans = 0;
    for (int i = 0; i < h; i++){
        for (int j = 0; j < w; j++){
            if (s[(i + j) % 7] == 'A'){
                ans++;
            }
        }
    }
    cout << ans<<endl;
    return 0;
}
  1. 数列差分

题目描述:

小蓝有两个长度均为 n 的数列 A={a1​,a2​,⋯,an​} 和 B={b1​,b2​,⋯,bn​},将两个数列作差定义为 C=A−B={c1​=a1​−b1​,c2​=a2​−b2​,⋯,cn​=an​−bn​}。小蓝将对数列 B 进行若干次操作,每次操作可以将数列 B 中的任意一个数更改为任意一个整数。在进行完所有操作后,小蓝可以按任意顺序将数列 B 重排,之后再计算数列 C。小蓝想知道,最少操作多少次可以使得数列 C 中的所有数都为正整数。

代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; cin>>n; vector<long long> a(n); vector<long long> b(n);
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++) cin>>b[i];
    sort(a.begin(),a.end()); sort(b.begin(),b.end());
    int i=0; int j=0,ans=0;
    while(i<n&&j<n){
        if(a[i]>b[j]){
            i++;
            j++;
            ans++;
        }else{
            i++;
        }
    }
    cout<<(n-ans)<<endl;
    return 0;
}
  1. 树上寻宝

小蓝正在一棵含有 n 个结点的树的根结点 1 上,他准备在这棵树上寻宝。结点 i 上有一个物品,价值为 wi​。然而,小蓝每次寻宝只能从根节点出发走不超过 k 步,每步只能选择走 1 条边或者 2 条边,之后会自动拾取最终停留的结点上的物品并被传送回根结点。请求出小蓝最终能获得的物品的总价值。

输入格式

输入的第一行包含两个正整数 n,k,用一个空格分隔。

第二行包含 n 个正整数 w1​,w2​,⋯,wn​,相邻整数之间使用一个空格分隔。

接下来 n−1 行,每行包含两个正整数 ui​,vi​,用一个空格分隔,表示结点 ui​ 和结点 vi​ 之间有一条边。

输出格式

输出一行包含一个整数表示答案。
解题思路:bfs, 定义d[i]: 节点i到根节点的边数距离, 每步选择的时候, 能走2就不会走1

⌈d[i]/2⌉<=k, d[i]<=2*k

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n;
    long long k;
    cin >> n >> k;
    vector<long long> w(n+1);
    for (int i = 1; i <= n; i++) {
        cin >> w[i];
    }
    vector<vector<int>> grap(n+1);
    for (int i = 0; i < n-1; i++) {
        int u, v;
        cin >> u >> v;
        grap[u].push_back(v);
        grap[v].push_back(u);
    }
    vector<int> d(n+1, -1);
    stack<int> st;
    d[1] = 0;
    st.push(1);
    while (!st.empty()) {
        int u = st.top(); st.pop();
        for (int v : grap[u]) {
            if (d[v] == -1) {
                d[v] = d[u] + 1;
                st.push(v);
            }
        }
    }
    long long ans = 0;
    long long maxD = 2 * k;
    for (int i = 1; i <= n; i++) {
        if (d[i] != -1 && d[i] <= maxD) {
            ans += w[i];
        }
    }
    cout << ans << endl;
    return 0;
}

7. 破解信息

在遥远的未来,星际旅行已经成为常态。宇航员小蓝在一次探险任务中,意外发现了一个古老的太空遗迹。遗迹中存放着一个数据存储器,里面记录着一段加密的信息。经过初步分析,小蓝发现这段信息可以被表示为一个字符串 S,而解密的关键,在于找出 S 中字典序最大的回文子序列。

  • 子序列 :指从原字符串中抽取若干个字符(可以不连续),按照它们在原字符串中的相对顺序排列所形成的新序列。例如,对于字符串 abc,其子序列包括 abcabacbcabc
  • 字典序 :指字符串按照字典中的排序规则比较大小的方式。对于两个字符串,从左到右逐字符比较,先出现较大字符的字符串字典序更大;若比较到某个字符串结束仍未找到不同的字符,则较短的字符串字典序较小。例如,abc < abd,而 ab < abc

现在,请你从字符串 S 中,找出字典序最大的回文子序列,帮助小蓝解开这段来自星际文明的信息。

输入格式

输入一行包含一个字符串 S,表示加密的信息。

输出格式

输出一行包含一个字符串,表示 S 中字典序最大的回文子序列
解题思路:统计字符串中字典序最大的字符, 然后统计其出现次数。

不管是奇数次和偶数次都是回文的。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    char a=*max_element(s.begin(),s.end()); 
    int count=0;
    for(char c:s){
        if(c==a) count++;
    } 
    string ans;
    for(int i=0;i<count;i++){
        ans+=a;
    }
    cout<<ans<<endl;
    return 0;
}

8.翻转硬币

题目描述

给定 n 行 m 列共 n×m 个硬币,对于任意一个硬币,我们将其价值视为与其相邻(指上、下、左、右相邻)的硬币中与其正反相同的硬币数的平方。

你可以进行任意次操作,每次可以选择任意一行并将该行的硬币全部翻转。

求所有硬币的价值之和最大可能是多少。

输入格式

输入的第一行包含两个正整数 n,m,用一个空格分隔。

接下来 n 行,每行包含 m 个 0 或 1,表示给定的 n×m 个硬币。

输出格式

输出一行包含一个整数表示答案。
解题思路:这道题是一道DP题, 但是无所谓啊,我们直接写暴力(注:追求前7题满分,最后一题直接打个暴力),欺骗自己AK了

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int dx[4] = {-1, 1, 0, 0};
const int dy[4] = {0, 0, -1, 1};
int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> a(n, vector<int>(m));
    for(int i = 0; i < n; i++){
        string s;
        cin >> s;               
        for(int j = 0; j < m; j++){
            a[i][j] = s[j] - '0';
        }
    }
    long long ans = 0;
    int maxNum = 1 << n;
    for(int k = 0; k < maxNum; k++){
        int g[20][20];
        for(int i = 0; i < n; i++){
            bool f = (k >> i) & 1;
            for(int j = 0; j < m; j++){
                g[i][j] = a[i][j] ^ (f ? 1 : 0);
            }
        }
        long long total = 0;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                int count = 0;
                for(int d = 0; d < 4; d++){
                    int ni = i + dx[d];
                    int nj = j + dy[d];
                    if(ni >= 0 && ni < n && nj >= 0 && nj < m){
                        if(g[ni][nj] == g[i][j]) {
                            count++;
                        }
                    }
                }
                total += (long long)count * count;
            }
        }
        ans = max(ans, total);
    }
    cout << ans << endl;
    return 0;
}

感谢大家的点赞和关注,你们的支持是我创作的动力!

吐槽:难道是上次出题太难了, 这次就....

相关推荐
元亓亓亓2 小时前
Java后端开发day36--源码解析:HashMap
java·开发语言·数据结构
小邓儿◑.◑3 小时前
C++武功秘籍 | 入门知识点
开发语言·c++
酷ku的森4 小时前
数据结构:链表
数据结构·链表
何其有幸.5 小时前
实验3-3 比较大小(PTA|C语言)
c语言·数据结构·算法
丶Darling.5 小时前
26考研 | 王道 | 数据结构笔记博客总结
数据结构·笔记·考研
杨筱毅5 小时前
【优秀三方库研读】【C++基础知识】odygrd/quill -- 折叠表达式
c++·三方库研读
东阳马生架构6 小时前
Sentinel源码—8.限流算法和设计模式总结二
算法·设计模式·sentinel
老饼讲解-BP神经网络6 小时前
一篇入门之-评分卡变量分箱(卡方分箱、决策树分箱、KS分箱等)实操例子
算法·决策树·机器学习
hjjdebug6 小时前
c++中的enum变量 和 constexpr说明符
c++·enum·constexpr
何其有幸.7 小时前
实验6-3 使用函数求特殊a串数列和(PTA|C语言)
c语言·数据结构·算法