蓝桥杯十六期模拟赛3题解【C++】

思路和代码仅供参考

填空题

一、质因数

【问题描述】

如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。请问, 2024 的最大的质因数是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

● 答案 23

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;

bool isprime(int x)
{
    if (x < 2)
        return false;
    for (int i = 2; i < sqrt(x); i++)
    {
        if (x % i == 0)
            return false;
    }
    return true;
}

int main()
{
    int n = 2024;
    for (int i = n; i >= 0; i--)
    {
        if (isprime(i) && n % i == 0)
        {
            cout << i << endl;
            break;
        }
    }
    return 0;
}

二、LCM

【问题描述】

对于两个整数 a, b,既是 a 的整数倍又是 b 的整数倍的数称为 a 和 b 的公倍数。公倍数中最小的正整数称为 a 和 b 的最小公倍数。请问, 2024 和 1024 的最小公倍数是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

● 答案259072

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;

int gcd(int a, int b)
{
    while (b != 0)
    {
        a %= b;
        swap(a, b);
    }
    return a;
}
int lcm(int a, int b)
{
    return (a * b) / gcd(a, b);
}
int main()
{
    int n = 2024, m = 1024;
    cout << lcm(m, n);
    return 0;
}

三、质因数

【问题描述】

如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。请问, 2024 的所有质因数的和是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

● 答案 36

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;

bool isprime(int x)
{
    if (x < 2)
        return false;
    for (int i = 2; i <= sqrt(x); i++)
    {
        if (x % i == 0)
            return false;
    }
    return true;
}

int main()
{
    int n = 2024;
    int ans = 0;
    for (int i = n; i > 0; i--)
    {
        if (isprime(i) && n % i == 0)
        {
            ans += i;
            cout << i << endl;
        }
    }
    cout << ans << endl;
    return 0;
}

四、质数

【问题描述】

请问,在不超过 2024 的数中,最大的质数是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

● 答案 2017

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;

bool isprime(int x)
{
    if (x < 2)
        return false;
    for (int i = 2; i <= sqrt(x); i++)
    {
        if (x % i == 0)
            return false;
    }
    return true;
}

int main()
{
    int n = 2024;
    for (int i = n; i > 0; i--)
    {
        if (isprime(i))
        {
            cout << i << endl;
            break;
        }
    }
    return 0;
}

五、互质

【问题描述】

如果两个整数 a, b 除了 1 以外,没有其它的公约数,则称整数 a 与 b 互质。请问,与 2024 互质的数中(包括1),第 2024 小的数是多少?

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

● 答案4655

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
vector<int> v;
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
int main()
{
    int n = 2024;
    int cnt = 1;
    for (int i = 1;; i++)
    {
        if (cnt == 2025)
            break;
        if (gcd(i, n) == 1)
        {
            v.push_back(i);
            cout << "第" << cnt << "次的数为  " << i << endl;
            cnt++;
        }
    }
    return 0;
}

六、找子串

【问题描述】

对于字符串 S=ANQNANBNQNANQNQNBNINQNQNANQNINANQNANBNQNANQNQNBNBNQNQNANQNINANQNANBNQNANQNQNBNINQNQNANQNINBNQNANBNQN ,请找到 S 的一个长度不超过 10 的子串 A,使得(A的长度)乘以(A在S中出现的次数)最大。请问这个子串是什么?(如果有多个满足条件的,请回答字典序最小的)。

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。

● 答案

NQN

69

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
// 滑动窗口枚举所有长度不超过10的子串
vector<string> findsubstring(string text)
{
    int n = text.length();
    string cursubstr;
    vector<string> substrs;
    for (int len = 1; len <= n && len <= 10; len++)
    {
        for (int i = 0; i <= n - len; i++)
        {
            cursubstr = text.substr(i, len);
            substrs.push_back(cursubstr);
        }
    }
    return substrs;
}
//
int findsubstringcount(string text, string pattern)
{
    int m = text.length();
    int n = pattern.length();
    int count = 0;
    for (int i = 0; i <= m - n; i++)
    {
        bool match = true;
        for (int j = 0; j < n; j++)
        {
            if (text[i + j] != pattern[j])
            {
                match = false;
                break;
            }
        }
        if (match)
            count++; // 匹配成功,计数器加 1
    }
    return count;
}
int main()
{
    string test = "ANQNANBNQNANQNQNBNINQNQNANQNINANQNANBNQNANQNQNBNBNQNQNANQNINANQNANBNQNANQNQNBNINQNQNANQNINBNQNANBNQN";
    vector<string> v = findsubstring(test);
    vector<int> v1;
    vector<string> ans;
    for (const string &s : v)
    {
        int count = findsubstringcount(test, s);
        int multi = s.length() * count;
        /*最大的数
        if (multi == 69)
        {
            cout << "找到了" << endl;
            cout << s << endl;
            cout << count << endl;
            cout << multi << endl;
        }
            */
    }
    return 0;
}

七、指数级枚举(DFS)

【问题描述】

如果一个字符串中只包含字符 0 和字符 1,则称为一个 01 串(包含全为 0 的串和全为 1 的串)。请问有多少个长度为 24 的 01 串,满足任意 5 个连续的位置中不超过 3 个位置的值为 1 。

【答案提交】

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

● 答案 162165

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
std::vector<int> pos; // 1的位置

void dfs(int begin)
{
    if (begin == 25)
    {
        ans++;
        return;
    }
    if (pos.size() < 2 || begin - pos[pos.size() - 2] > 4)
    {
        pos.push_back(begin); // 1
        dfs(begin + 1);
        pos.pop_back();
    }
    dfs(begin + 1); // 0
}

int main()
{
    IOS;
    int ans = 0;
    dfs(1);
    out << ans << endl;
    return 0;
}

代码题

一、数学

【问题描述】

小蓝种了一块玉米地,玉米地长 n 米,宽 m 米,每平方米产玉米 a 千克。请问小蓝的玉米地一共能产多少千克玉米?

【输入格式】

输入三行。第一行包含一个正整数 n ,第二行包含一个正整数 m ,第三行包含一个正整数 a 。

【输出格式】

输出一行,包含一个整数,表示答案。

【样例输入】

20 24 900

【样例输出】

432000

【评测用例规模与约定】

对于所有评测用例,1 <= n <= 1000, 1 <= m <= 1000, 1 <= a <= 2000。

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;

int main()
{
    IOS;
    int n, m, a;
    cin >> n >> m >> a;
    cout << n * m * a << endl;
    return 0;
}

二、贪心

【问题描述】

小蓝有一个数组 a[1], a[2], …, a[n], 一个“再创新高”的位置是指一个位置 p ,a[p] 的值比之前每个位置的值都大。请求出小蓝的数组中有多少个再创新高的位置。

【输入格式】

输入的第一行包含一个整数 n 。第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。

【输出格式】

输出一行,包含一个整数,表示答案。

【样例输入】

8

1 2 3 4 5 6 6 6

【样例输出】

6

【样例输入】

9

3 2 1 6 5 4 9 8 7

【样例输出】

3

【评测用例规模与约定】

对于 30% 的评测用例,1 <= n <= 100,0 <= a[i] <= 1000。

对于 60% 的评测用例,1 <= n <= 1000,0 <= a[i] <= 1000。

对于所有评测用例,1 <= n <= 10000,0 <= a[i] <= 1000000。

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
const int N = 1e6;
int a[N];
int main()
{
    IOS;
    int n;
    cin >> n;
    int ans = 0;
    int maxx = INT_MIN;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= n; i++)
    {
        if (a[i] > maxx)
        {
            ans++;
            maxx = a[i];
        }
    }
    cout << ans << endl;
    return 0;
}

三、排序串

【问题描述】

给定四个字符串 a, b, c, d,请将这四个字符串按照任意顺序依次连接拼成一个字符串。请问拼成的字符串字典序最小是多少?

【输入格式】

输入四行,每行包含一个字符串。

【输出格式】

输出一行包含一个字符串,表示答案。

【样例输入】

LAN LAN QIAO BEI

【样例输出】

BEILANLANQIAO

【评测用例规模与约定】

对于所有评测用例,输入的字符串非空串,由大写字母组成,长度不超过 1000 。

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
bool cmp(const string& a,const string& b) {
    return a + b < b + a;
}
int main()
{
    IOS;
    string a, b, c, d;
    cin >> a >> b >> c >> d;
    vector<string> words = {a, b, c, d};
    sort(words.begin(), words.end(),cmp);
    for (int i = 0; i < words.size(); i++)
    {
        cout << words[i];
    }
    return 0;
}

四、模拟

【问题描述】

蓝桥村正在给村民们发放礼物。礼物通过一个礼物发放机完成。村民们在机器前排着队领取礼物。每个礼物有一个价值 v[i] ,有的高,有的低。每位村民有自己对于礼物的期望值 e[i] 。礼物发放机每次会显示一个礼物,

如果礼物的价值大于等于村民的期望值,村民就会高兴地把礼物拿走,并离开礼物发放机。

如果礼物的价值比村民的期望值低,村民会让这个礼物取消,并让礼物发放机显示下一个礼物,并重新检查是否满足期望。

村民会重复让礼物发放机显示下⼀个礼物,直到礼物发放机没有更多可以显示的礼物或礼物的价值大于等于自己的期望值。

如果礼物发放机中的所有礼物都显示完了,那么还没领到礼物的村民就无法领取礼物了。

如果所有的村民都领到了礼物,而礼物发放机还有礼物显示,村民们也不会再领取礼物。

现在,小蓝知道了每位村民的期望值,也知道了礼物发放机上礼物的显示顺序,请问总共有多少村民拿到了礼物?

【输入格式】

输入的第一行包含一个整数 n ,表示村民的个数。

第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示排队的每位村民的期望值 e[i] 。

第三行包含一个整数 m ,表示礼物发放机会显示的礼物个数。

第四行包含 m 个整数,相邻数之间使用一个空格分隔,依次表示礼物发放机显示的礼物的价值 v[i] 。

【输出格式】

输出一行,包含一个整数,表示答案。

【样例输入】

6

6 5 5 3 6 0

9

9 9 8 2 4 4 3 5 3

【样例输出】

4

【样例说明】

前 4 位村民依次取到了第 1, 2, 3, 5 件礼物。后面的礼物未能满足第 5 位村民。

【评测用例规模与约定】

对于 30% 的评测用例,1 <= n, m <= 20 , 0 <= e[i], v[i] <= 100 。

对于 60% 的评测用例,1 <= n, m <= 300 , 0 <= e[i], v[i] <= 10000 。

对于所有评测用例,1 <= n, m <= 10000 , 0 <= e[i], v[i] <= 1000000 。

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
vector<ll> e;
vector<ll> v;
int m;
int n;
int main()
{
    IOS;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        ll tmp;
        cin >> tmp;
        e.push_back(tmp);
    }
    for (int i = 0; i < m; i++)
    {
        ll tmp;
        cin >> tmp;
        v.push_back(tmp);
    }
    int ans = 0;
    for (int i = 0; i < e.size(); i++)
    {
        for (int j = 0; j < v.size(); j++)
        {
            if (v[j] >= e[i])
            {
                ans++;                  // 拿走礼物
                v.erase(v.begin() + j); // 删除第j个元素
                e.erase(e.begin() + i); // 删除第i个元素
                i--;
                break;
            }
            else
            {
                continue;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

五、前缀和

【问题描述】

小蓝有一个 n 行 m 列的矩阵 a[i][j] ,他想着矩阵中找出一个“十”字形状的区域,使得区域内的值的和最大。一个“十”字形状的区域可以由两个行号 r1 、 r2 和两个列号 c1 、 c2 表示。“十”字的区域内包括第 r1 行到 r2 行的所有元素,以及第 c1 列到 c2 列的所有元素,既不在这几行也不在这几列的元素不在区域内。为了保证是一个“十”字的形状,必须满足 1 < r1 <= r2 < n,1 < c1 <= c2 < m。

【输入格式】

输入的第一行包含两个整数 n, m ,分别表示行数和列数。接下来 n 行,每行包含 m 个整数,相邻数之间使用一个空格分隔,依次表示矩阵的每行每列的值,本部分的第 i 行第 j 列表示 a[i][j] 。

【输出格式】

输出一行包含一个整数,表示最大的和。

【样例输入】

5 61 -1 2 -2 3 -3-1 2 -2 3 -3 42 -2 3 -3 4 -4-2 3 -3 4 -4 53 -3 4 -4 5 -5

【样例输出】

14

【样例说明】

有两种方法可以得到最大的和。

第一种是取 r1=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 。

对于 60% 的评测用例,3 <= n, m <= 100 ,-1000 <= a[i][j] <= 1000 。

对于所有评测用例,3 <= n <= 100, 3 <= m <= 5000 ,-1000 <= a[i][j] <= 1000 。

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
const int MIN = -1e9;
const int MAXN = 105;
const int MAXM = 5005;

int mp[MAXN][MAXM];
int prefix[MAXN][MAXM];
int mpp[MAXM];
int ans = MIN;
int n, m;
void initialize()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> mp[i][j];
        }
    }

    for (int i = 0; i <= n; i++)
    {
        prefix[i][0] = 0;
    }
    for (int j = 0; j <= m; j++)
    {
        prefix[0][j] = 0;
    }
}

void calprefix()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            prefix[i][j] = mp[i][j] +
                           prefix[i - 1][j] +
                           prefix[i][j - 1] -
                           prefix[i - 1][j - 1];
        }
    }
}

void solve()
{
    for (int r1 = 2; r1 < n; r1++)
    {
        for (int r2 = r1; r2 < n; r2++)
        {
            int x = prefix[r2][m] - prefix[r1 - 1][m];

            for (int ind = 1; ind <= m; ind++)
            {
                mpp[ind] = prefix[n][ind] - (prefix[r2][ind] - prefix[r1 - 1][ind]);
            }

            int minn = 0;
            int res = MIN;

            for (int i = 1; i <= m; i++)
            {
                res = max(res, mpp[i] - minn);
                minn = min(minn, mpp[i]);
            }
            ans = max(ans, res + x);
        }
    }
    cout << ans << endl;
}
int main()
{
    IOS;
    cin >> n >> m;
    initialize();
    calprefix();
    solve();
    return 0;
}
### 第十四届蓝桥杯省赛 C++ B组 题目解析 以下是关于第十四届蓝桥杯省赛 C++ B组的部分题目解析及其相关内容: #### 一、整体趋势分析 近年来,蓝桥杯竞赛的难度有所调整,不再单纯依赖“暴力求解”,而是更加注重动态规划 (DP) 和搜索图论的应用。这种变化使得参赛者需要具备更强的算法设计能力和逻辑思维能力[^1]。 #### 二、具体题目解析 由于完整的官方题解可能无法完全公开获取,以下提供部分典型题目的思路和解答方法: ##### 1. 填充问题(Greedy Algorithm) 此题属于典型的贪心类问题。其核心在于如何通过局部最优策略实现全局最优效果。参考某篇博客中的解决方案可知,在处理此类问题时应优先考虑资源分配的最大化利用原则[^2]。 ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; // 输入数据量大小n vector<int> a(n); for(auto &x : a){ cin>>x; } sort(a.begin(),a.end()); long long sum=0LL; for(int i=0;i<n/2;i++)sum +=(long long)(a[n-i-1]-a[i]); cout<<sum<<endl; } ``` 上述代码片段展示了针对该问题的一种高效解决方式——通过对数组排序并计算差值来达到目标函数最大化的目的。 ##### 2. 翻转操作(Thinking Problem) 对于涉及字符串或者序列变换的操作,《翻转》这类题目往往考验选手的基础编程技巧与灵活运用能力。通常情况下,可以通过模拟实际过程完成任务;但在某些特殊场景下,则需引入额外的数据结构辅助运算以提升效率。 ```cpp string reverseString(string s, int k){ string res = ""; bool flag=true; while(!s.empty()){ if(flag && k<=s.size()){// 当前段长度大于等于k则反转前k个字符 string temp=s.substr(0,k);reverse(temp.begin(),temp.end());res+=temp;s.erase(0,k); }else{ res+=flag?s:s.substr(s.size()-k+1,s.size());// 不足k个按原样加入结果串 break; } flag=!flag;// 切换状态 } return res+s; } ``` 这里给出了一种基于条件判断逐步构建最终输出的方法,体现了程序设计过程中清晰逻辑的重要性。 #### 总结说明 以上仅列举了两个具有代表性的例子,并附上了相应的实现方案供学习交流之用。更多深入探讨可查阅相关资料进一步了解[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值