第16届蓝桥杯第三期模拟赛 C++组
题目解析 思路和答案不保证正确
1.填空
如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。
请问, 2024 的最大的质因数是多少?
因为是填空题,所以直接枚举2023~2 ,第一个即是质数也是2024的因数的数就是答案。
23
2.填空
对于两个整数a, b,既是a的整数倍又是b的整数倍的数称为a和b的公倍数。公倍数中最小的正整数称为a和b的最小公倍数。
请问,2024和1024的最小公倍数是多少?
经典求lcm
:
l
c
m
(
a
,
b
)
=
a
∗
b
g
c
d
(
a
∗
b
)
lcm(a, b)=\frac{a*b}{gcd(a*b)}
lcm(a,b)=gcd(a∗b)a∗b
根据公式算出答案即可
259072
3.填空
如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。
请问, 2024 的所有质因数的和是多少?
第一个填空使用的代码已经计算出了2024的质因数为:23,11,8,4,2 ,加到一起就可以了
36
4.填空
请问,在不超过 2024 的数中,最大的质数是多少?
枚举2023~2,找到第一个质数
void solve(){
auto check = [](int x) {
for(int i = 2; i < x; i++) {
if(x % i == 0) return false;
}
return true;
};
for(int i = 2024; i >= 0; -- i) {
if(check(i)) {
std::cout << i << "\n";
return ;
}
}
}
2017
5.填空
如果两个整数 a, b 除了 1 以外,没有其它的公约数,则称整数 a 与 b 互质。
请问,与 2024 互质的数中(包括1),第 2024 小的数是多少?
while循环从1开始找满足gcd (x ,2024) = = 1 的数,找第2024个
void solve(){
int sum = 0;
for(int i = 1; i < 1e7; i++) {
if(gcd(i, 2024) == 1) sum++;
if(sum == 2024) {std::cout << i << “\n”; return; }
}
}
4655
6.填空
对于字符串 S=ANQNANBNQNANQNQNBNINQNQNANQNINANQNANBNQNANQNQNBNBNQNQNANQNINANQNANBNQNANQNQNBNINQNQNANQNINBNQNANBNQN ,请找到 S 的一个长度不超过 10 的子串 A,使得(A的长度)乘以(A在S中出现的次数)最大。
请问这个子串是什么?(如果有多个满足条件的,请回答字典序最小的)。
字符串不长,直接枚举所有长度不超过10的子串,然后将他们的出现次数记录在字典中,然后在字典中找答案就好
NQN
7.填空
如果一个字符串中只包含字符 0 和字符 1,则称为一个 01 串(包含全为 0 的串和全为 1 的串)。
请问有多少个长度为 24 的 01 串,满足任意 5 个连续的位置中不超过 3 个位置的值为 1 。
长度为24的01串总共有 ( 2 24 ) (2^{24}) (224)个,大约 ( 1.7 × 1 0 7 ) (1.7\times10^{7}) (1.7×107),可以花点时间暴力枚举所有的字符串
bool check(int x) {
int lst[24];
int count = 0;
for (int i = 0; i < 24; ++i) {
if (x & (1 << i)) {
lst[count++] = i;
}
}
if (count <= 2) {
return true;
}
for (int i = 0; i < count - 2; ++i) {
if (lst[i + 2] - lst[i] <= 4) {
return false;
}
}
return true;
}
void solve(){
clock_t tik = clock();
int ans = 0;
for (int x = 0; x < (1 << 24); ++x) {
if (check(x)) {
ans++;
}
}
clock_t tok = clock();
double time_used = ((double)(tok - tik)) / CLOCKS_PER_SEC;
cout << time_used << endl;
cout << ans << endl;
}
2963628
- 玉米地
题意
【问题描述】
小蓝种了一块玉米地,玉米地长 n 米,宽 m 米,每平方米产玉米 a 千克。请问小蓝的玉米地一共能产多少千克玉米?
【输入格式】
输入三行。第一行包含一个正整数 n ,第二行包含一个正整数 m ,第三行包含一个正整数 a 。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
20
24
900
【样例输出】
432000
【评测用例规模与约定】
对于所有评测用例,1 <= n <= 1000, 1 <= m <= 1000, 1 <= a <= 2000。
思路 : 输出乘积即可 n * m * a
void solve1(){
int n, m, a; std::cin >> n >> m >> a;
std::cout << n * m * a << "\n";
}
9.再创新高
题意
【问题描述】
小蓝有一个数组 a[1], a[2], …, a[n], 一个“再创新高”的位置是指一个位置 p ,a[p] 的值比之前每个位置的值都大。
请求出小蓝的数组中有多少个再创新高的位置。
【输入格式】
输入的第一行包含一个整数 n 。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。
【输出格式】
输出一行,包含一个整数,表示答案。
void solve2() {
In; vector<int> a(n);
f std::cin >> a[i];
int ans = 1, mx = a[0];
f {
if(a[i] > mx) {
ans++;
mx = a[i];
}
}
std::cout << ans << "\n";
}
10.四个字符串拼接
题意
【问题描述】
给定四个字符串 a, b, c, d,请将这四个字符串按照任意顺序依次连接拼成一个字符串。
请问拼成的字符串字典序最小是多少?
【输入格式】
输入四行,每行包含一个字符串。
【输出格式】
输出一行包含一个字符串,表示答案。
【样例输入】
LAN
LAN
QIAO
BEI
【样例输出】
BEILANLANQIAO
思路: 四个字符串拼接只有(A_{4}^4) 种可能,直接枚举所有可能的情况,找到最小的字符串即可。
#include<bits/stdc++.h>
typedef long long ll; // 确保 ll 在使用前被定义
using namespace std;
using i64 = long long;
#define f for(int i = 0; i < n;++i)
#define ff for(int i = 1; i <= n;++i)
#define int long long
#define In ll n; std::cin >> n;
void solve4() {
In; std::vector<int> e(n); f std::cin >> e[i];
int m; std::cin >> m; std::vector<int> v(m);
for(int i = 0; i < m ; ++ i) std::cin >> v[i];
int start = 0;
int ans = 0;
for(int i = 0; i < n; i++) {
for(; start < m; ) {
if(v[start] >= e[i]) {
start++;
ans++;
break;
}
start++;
}
}
std::cout << ans << "\n";
}
11.领取礼物
题意
【问题描述】
蓝桥村正在给村民们发放礼物。礼物通过一个礼物发放机完成。
村民们在机器前排着队领取礼物。
每个礼物有一个价值 v[i] ,有的高,有的低。每位村民有自己对于礼物的期望值 e[i] 。
礼物发放机每次会显示一个礼物,如果礼物的价值大于等于村民的期望值,村民就会高兴地把礼物拿走,并离开礼物发放机。如果礼物的价值比村民的期望值低,村民会让这个礼物取消,并让礼物发放机显示下一个礼物,并重新检查是否满足期望。村民会重复让礼物发放机显示下⼀个礼物,直到礼物发放机没有更多可以显示的礼物或礼物的价值大于等于自己的期望值。
如果礼物发放机中的所有礼物都显示完了,那么还没领到礼物的村民就无法领取礼物了。
如果所有的村民都领到了礼物,而礼物发放机还有礼物显示,村民们也不会再领取礼物。
现在,小蓝知道了每位村民的期望值,也知道了礼物发放机上礼物的显示顺序,请问总共有多少村民拿到了礼物?
【输入格式】
输入的第一行包含一个整数 n ,表示村民的个数。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示排队的每位村民的期望值 e[i] 。
第三行包含一个整数 m ,表示礼物发放机会显示的礼物个数。
第四行包含 m 个整数,相邻数之间使用一个空格分隔,依次表示礼物发放机显示的礼物的价值 v[i] 。
【输出格式】
输出一行,包含一个整数,表示答案。
思路
模拟礼物分发的过程即可
使用for循环按顺序枚举每个村民,对于每个村民使用while循环来查找符合的礼物。
当所有村民都领到礼物,或者所有的礼物都分发完就结束循环
void solve4() {
In; std::vector<int> e(n); f std::cin >> e[i];
int m; std::cin >> m; std::vector<int> v(m);
for(int i = 0; i < m ; ++ i) std::cin >> v[i];
int start = 0;
int ans = 0;
for(int i = 0; i < n; i++) {
for(; start < m; ) {
if(v[start] >= e[i]) {
start++;
ans++;
break;
}
start++;
}
}
std::cout << ans << "\n";
}
- 十字矩阵
题意
【问题描述】
小蓝有一个 n 行 m 列的矩阵 a [ i ] [ j ] a[i][j]a[i][j],他想着矩阵中找出一个“十”字形状的区域,使得区域内的值的和最大。
一个“十”字形状的区域可以由两个行号r 1 r1r1 、 r 2 r2r2 和两个列号 c 1 c1c1 、 c 2 c2c2 表示。“十”字的区域内包括第 r 1 r1r1 行到 r 2 r2r2 行的所有元素,以及第 c 1 c1c1 列到 c 2 c2c2 列的所有元素,既不在这几行也不在这几列的元素不在区域内。
为了保证是一个“十”字的形状,必须满足 1 < r 1 < = r 2 < n , 1 < c 1 < = c 2 < m 1 < r1 <= r2 < n,1 < c1 <= c2 < m1<r1<=r2<n,1<c1<=c2<m。
【输入格式】
输入的第一行包含两个整数 $n, m $,分别表示行数和列数。
接下来 n nn 行,每行包含 m mm整数,相邻数之间使用一个空格分隔,依次表示矩阵的每行每列的值,本部分的第 i ii 行第 j jj 列表示 a [ i ] [ j ] a[i][j]a[i][j] 。
【输出格式】
输出一行包含一个整数,表示最大的和。
【样例输入】
5 6
1 -1 2 -2 3 -3
-1 2 -2 3 -3 4
2 -2 3 -3 4 -4
-2 3 -3 4 -4 5
3 -3 4 -4 5 -5
【样例输出】
14
【样例说明】
有两种方法可以得到最大的和。第一种是取 r 1 = 2 , r 2 = 4 , c 1 = 3 , c 2 = 5 r1=2, r2=4, c1=3, c2=5r1=2,r2=4,c1=3,c2=5,第二种是取$ r1=2, r2=4, c1=5, c2=5 $。
【评测用例规模与约定】
对于 30% 的评测用例,3 < = n , m < = 30 , − 1000 < = a [ i ] [ j ] < = 1000 3 <= n, m <= 30 ,-1000 <= a[i][j] <= 10003<=n,m<=30,−1000<=a[i][j]<=1000 。
对于 60% 的评测用例,3 < = n , m < = 100 , − 1000 < = a [ i ] [ j ] < = 1000 3 <= n, m <= 100 ,-1000 <= a[i][j] <= 10003<=n,m<=100,−1000<=a[i][j]<=1000 。
对于所有评测用例,$3 <= n <= 100, 3 <= m <= 5000 ,-1000 <= a[i][j] <= 1000 $。
思路
部分分
本题难度明显高于其他题目,可以考虑拿部分分:
用总减去十字部分以外的和,即十字部分以外的和最小。首先预处理四个顶点为原点的前缀和,接着枚举1-n这些行和最小(十字部分上面以外和最小),接着枚举n-1这些行和最下(十字部分下面以外和最小),最后拿总和-(上面加下面)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e2+5;
const int M=5e3+5;
ll a[N][M],pre1[N][M],pre2[N][M],pre3[N][M],pre4[N][M];
ll mn1[N],mn2[N];
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n,m;
cin>>n>>m;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) cin>>a[i][j];
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j) pre1[i][j]=pre1[i][j-1]+pre1[i-1][j]-pre1[i-1][j-1]+a[i][j];
for (int i=1;i<=n;++i)
for (int j=m;j>=1;j--) pre2[i][j]=pre2[i-1][j]+pre2[i][j+1]-pre2[i-1][j+1]+a[i][j];
for (int i=n;i>=1;i--)
for (int j=1;j<=m;++j) pre3[i][j]=pre3[i][j-1]+pre3[i+1][j]-pre3[i+1][j-1]+a[i][j];
for (int i=n;i>=1;i--)
for (int j=m;j>=1;j--) pre4[i][j]=pre4[i+1][j]+pre4[i][j+1]-pre4[i+1][j+1]+a[i][j];
mn1[0]=1e9;
for (int i=1;i<=n;++i)
{
ll t=1e9;
vector<ll> t1(m+4,1e9),t2(m+4,1e9);
for (int j=1;j<=m;++j) t1[j]=min(t1[j-1],pre1[i][j]);
for (int j=m;j>=1;j--) t2[j]=min(t2[j+1],pre2[i][j]);
t1[0]=t2[m+1]=0;
for (int j=2;j<m;++j) t=min(t,t1[j-1]+t2[j+1]);
mn1[i]=min(t,mn1[i-1]);
}
mn1[0]=0;
mn2[n+1]=1e9;
for (int i=n;i>=1;i--)
{
ll t=1e9;
vector<ll> t1(m+4,1e9),t2(m+4,1e9);
for (int j=1;j<=m;++j) t1[j]=min(t1[j-1],pre3[i][j]);
for (int j=m;j>=1;j--) t2[j]=min(t2[j+1],pre4[i][j]);
t1[0]=t2[m+1]=0;
for (int j=2;j<m;++j) t=min(t,t1[j-1]+t2[j+1]);
mn2[i]=min(mn2[i+1],t);
}
mn2[n+1]=0;
ll ans=1e9;
for (int i=2;i<n;++i) ans=min(ans,mn1[i-1]+mn2[i+1]);
cout<<pre1[n][m]-ans;
return 0;
}