由于官方没有公布题目的数据, 所以代码仅供参考
- 密密摆放
题目链接: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;
}
- 脉冲强度之和
题目描述
在蓝桥电子工坊,工程师小蓝正在设计一款智能脉冲生成器,用于驱动一种新型设备。该设备的运行依赖于特定的脉冲强度,用正整数 p 表示,其必须满足以下三个条件:
可由连续 10 个正整数之和组成:即存在一个正整数 k,使得脉冲强度 p=k+(k+1)+(k+2)+⋯+(k+9)。
各个数位上的数字都相同:例如 1111、22222、333333 等。
数值不超过 20255202:即 1≤p≤20255202。
通过计算所有符合条件的脉冲强度之和,小蓝能够优化设备运行模式。对此,请帮助他计算这一总和。
解题思路:
p=k+(k+1)+(k+2)+⋯+(k+9) => p=(k+k+9)*10/2=10*k+45
解 p=10*k+45, 看k有没有解, 就能验证条件1了
接着验证p的每一位是否相等
按顺序枚举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;
}
- 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;
}
- 旗帜
小蓝要画一个 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;
}
- 数列差分
题目描述:
小蓝有两个长度均为 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;
}
- 树上寻宝
小蓝正在一棵含有 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
,其子序列包括a
、b
、c
、ab
、ac
、bc
和abc
。- 字典序 :指字符串按照字典中的排序规则比较大小的方式。对于两个字符串,从左到右逐字符比较,先出现较大字符的字符串字典序更大;若比较到某个字符串结束仍未找到不同的字符,则较短的字符串字典序较小。例如,
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;
}
感谢大家的点赞和关注,你们的支持是我创作的动力!
吐槽:难道是上次出题太难了, 这次就....