蓝桥杯第十五届C++B组省赛真题解析

news2025/7/8 16:05:38

蓝桥杯第十五届C++B组省赛真题解析


一、宝石组合https://www.lanqiao.cn/problems/19711/learning/

解题思路

题目要求找到三个数,使得它们的最大公约数(GCD)尽可能大,并在GCD相同的情况下选择数值最小的三个数。以下是分步解析:

  1. ​公式化简​​:

    • 通过数学推导,将三个数的最小公倍数(LCM)转化为涉及GCD的表达式:
      LCM ( a , b , c ) = a × b × c × GCD ( a , b , c ) GCD ( a , b ) × GCD ( b , c ) × GCD ( a , c ) \text{LCM}(a, b, c) = \frac{a \times b \times c \times \text{GCD}(a, b, c)}{\text{GCD}(a, b) \times \text{GCD}(b, c) \times \text{GCD}(a, c)} LCM(a,b,c)=GCD(a,b)×GCD(b,c)×GCD(a,c)a×b×c×GCD(a,b,c)
    • 题目中的目标函数 $ S $ 最终简化为三个数的最大公约数:
      S = GCD ( a , b , c ) S = \text{GCD}(a, b, c) S=GCD(a,b,c)
  2. ​预处理因数​​:

    • 对每个输入的数,计算其所有因数,并将该数记录到对应因数的列表中。
    • ​例如​​:数 12 的因数为 1, 2, 3, 4, 6, 12 ,每个因数的列表都会添加12。
  3. ​搜索最大GCD​​:

    • ​从大到小遍历所有可能的因数​​ d ,检查对应列表是否包含至少三个数。
    • 第一个满足条件的 $ d $ 即为最大可能的GCD,因为更大的因数已被遍历过且不满足条件。
  4. ​选择最小字典序​​:

    • 对满足条件的列表排序,取前三个最小的数,确保在相同GCD时结果字典序最小。

公式推导细节

  1. ​三数LCM的展开​​:
    LCM ( a , b , c ) = a ⋅ b ⋅ c GCD ( a , b ) ⋅ GCD ( b , c ) ⋅ GCD ( a , c ) ⋅ GCD ( a , b , c ) \text{LCM}(a, b, c) = \frac{a \cdot b \cdot c}{\text{GCD}(a, b) \cdot \text{GCD}(b, c) \cdot \text{GCD}(a, c)} \cdot \text{GCD}(a, b, c) LCM(a,b,c)=GCD(a,b)GCD(b,c)GCD(a,c)abcGCD(a,b,c)

  2. ​目标函数 $ S $ 的化简​​:
    S = LCM ( a , b , c ) ⋅ GCD ( a , b ) ⋅ GCD ( b , c ) ⋅ GCD ( a , c ) a ⋅ b ⋅ c = GCD ( a , b , c ) S = \frac{\text{LCM}(a, b, c) \cdot \text{GCD}(a, b) \cdot \text{GCD}(b, c) \cdot \text{GCD}(a, c)}{a \cdot b \cdot c} = \text{GCD}(a, b, c) S=abcLCM(a,b,c)GCD(a,b)GCD(b,c)GCD(a,c)=GCD(a,b,c)


算法步骤

  1. ​预处理​​:

    • 遍历每个数,分解其所有因数,将数存入对应因数的容器中。
    • ​时间复杂度​​:$ O(n \sqrt{\text{max_value}}) $,其中 $ n $ 是输入数的个数。
  2. ​枚举最大GCD​​:

    • 从最大可能的因数(如 $ 10^5 $)开始倒序遍历,找到第一个满足条件的因数。
    • ​时间复杂度​​:$ O(\text{max_value}) $。
  3. ​输出结果​​:

    • 对符合条件的三数排序,选择字典序最小的组合。
    • ​时间复杂度​​:$ O(k \log k) $,其中 $ k $ 是容器中数的数量。

#include <bits/stdc++.h>
using namespace std;
vector<int> a[100010];
int main()
{
  int n;
  cin >> n;
  for(int i=0; i<n; i++){
    int temp;
    cin >> temp;

    for(int j=1; j*j<=temp; j++){
      //找到temp的所有因数,并将temp插入到每个因数的后面
       if(temp%j==0){
      
         a[j].push_back(temp);
         if(j!=temp/j)//防止重复在开方数后插入temp
         a[temp/j].push_back(temp);
       }
    }
  }
  for(int i=100000;i>=0; i--){
    if(a[i].size()>=3){
      sort(a[i].begin(),a[i].end());
      cout << a[i][0]<< " "<<  a[i][1]<< " " << a[i][2];
      return 0;
    }
  }
  return 0;
}

二、拔河

https://www.lanqiao.cn/problems/19713/learning/

问题描述

给定一个表示同学力量值的数组,要求找到​​两个不同子数组和的最小差值​​。允许子数组重叠甚至完全重合(这意味着差值为0是可能的)。


算法思路

1. 前缀和计算
  • ​目标​​:快速计算任意子数组的和,避免双重循环累加。
  • ​方法​​:构建前缀和数组 pre[],其中 pre[i] 表示原数组前 i 项的和。
    p r e [ i ] = { a [ 0 ] if  i = 0 p r e [ i − 1 ] + a [ i ] if  i > 0 pre[i] = \begin{cases} a[0] & \text{if } i = 0 \\ pre[i-1] + a[i] & \text{if } i > 0 \end{cases} pre[i]={a[0]pre[i1]+a[i]if i=0if i>0
2. 生成所有子数组和
  • ​步骤​​:
    1. 通过双重循环枚举所有可能的子数组起止点 ij
    2. 使用前缀和公式计算区间 [i, j] 的和:
      sum ( i , j ) = { p r e [ j ] if  i = 0 p r e [ j ] − p r e [ i − 1 ] if  i > 0 \text{sum}(i, j) = \begin{cases} pre[j] & \text{if } i = 0 \\ pre[j] - pre[i-1] & \text{if } i > 0 \end{cases} sum(i,j)={pre[j]pre[j]pre[i1]if i=0if i>0
    3. 将所有子数组和存入集合 s 中。
3. 排序优化查找
  • ​关键性质​​:排序后的数组中,最小差值必然出现在相邻元素之间。
  • ​步骤​​:
    1. 对集合 s 排序。
    2. 遍历排序后的数组,计算相邻元素的差值,记录最小值。

时间复杂度

步骤时间复杂度
前缀和计算O(n)
生成所有子数组和O(n^2)
排序子数组和集合O(n^2 \log n)

​适用场景​​:当 $ n \leq 1000 $ 时,算法效率可接受。


代码实现

#include <bits/stdc++.h>
using namespace std;
vector<int> a[100010];
int main()
{
  int n;
  cin >> n;
  for(int i=0; i<n; i++){
    int temp;
    cin >> temp;

    for(int j=1; j*j<=temp; j++){
      //找到temp的所有因数,并将temp插入到每个因数的后面
       if(temp%j==0){
      
         a[j].push_back(temp);
         if(j!=temp/j)//防止重复在开方数后插入temp
         a[temp/j].push_back(temp);
       }
    }

  }
  for(int i=100000;i>=0; i--){
    if(a[i].size()>=3){
      sort(a[i].begin(),a[i].end());
      cout << a[i][0]<< " "<<  a[i][1]<< " " << a[i][2];
      return 0;
    }
  }
  return 0;
}


三、数字接龙

https://www.lanqiao.cn/problems/19712/learning/


#include <bits/stdc++.h>
using namespace std;

const int N = 11; // 定义棋盘的最大大小为11×11
int n, k; // n为棋盘大小,k为数字循环的范围
int g[N][N]; // 存储棋盘上的数字
int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; // 定义8个方向的x坐标偏移
int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1}; // 定义8个方向的y坐标偏移
string path; // 存储路径的方向编号
bool st[N][N]; // 标记棋盘上的格子是否被访问过
bool edge[N][N][N][N]; // 检查路径是否交叉

// 深度优先搜索函数,用于寻找路径
bool dfs(int a, int b) {
    // 如果到达右下角格子,检查路径长度是否为n*n-1(因为起点不计入路径)
    if (a == n - 1 && b == n - 1)
        return path.size() == n * n - 1;

    st[a][b] = true; // 标记当前格子已访问
    for (int i = 0; i < 8; i++) { // 遍历8个方向
        int x = a + dx[i], y = b + dy[i]; // 计算目标格子的坐标
        // 检查目标格子是否越界、是否访问过、数字是否满足循环序列要求
        if (x < 0 || x >= n || y < 0 || y >= n) continue;
        if (st[x][y]) continue;
        if (g[x][y] != (g[a][b] + 1) % k) continue;
        // 检查路径是否交叉(对于斜向移动,检查是否有反向的路径)
        if (i % 2 && (edge[a][y][x][b] || edge[x][b][a][y])) continue;

        edge[a][b][x][y] = true; // 标记路径
        path += i + '0'; // 将方向编号加入路径
        if (dfs(x, y)) return true; // 递归搜索下一个格子
        path.pop_back(); // 回溯,移除路径中的最后一个方向
        edge[a][b][x][y] = false; // 回溯,取消路径标记
    }
    st[a][b] = false; // 回溯,取消当前格子的访问标记
    return false; // 如果所有方向都无法到达终点,返回false
}

int main() {
    cin >> n >> k; // 输入棋盘大小和数字循环范围
    for (int i = 0; i < n; i++) // 读取棋盘上的数字
        for (int j = 0; j < n; j++)
            cin >> g[i][j];

    // 从起点(0,0)开始搜索路径
    if (!dfs(0, 0))
        cout << -1 << endl; // 如果没有找到路径,输出-1
    else
        cout << path << endl; // 输出路径的方向编号序列

    return 0;
}

---

四、小球反弹

https://www.lanqiao.cn/problems/19732/learning/

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
  int  x=343720,y=233333;
  long long t=1;

  while(1){
    if(15*t % x == 0 && 17*t%y == 0) break;
    t++;//当小球弹到长方形的某个角后,将原路返回;
  }
  long long t1 = t*t*15*15+t*t*17*17;
  
  printf("%.2f",2*sqrt(t1));
  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2331913.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW商业软件开发注意问题

在 LabVIEW 商业软件开发进程中&#xff0c;性能优化、界面设计及兼容性与扩展性&#xff0c;对软件品质、用户体验和市场适配性起着决定性作用。下面&#xff0c;借助多个LabVIEW 编程特性的实际案例&#xff0c;深入分析这些方面的开发要点。 一、性能优化&#xff1a;提升软…

Java 中 SQL 注入问题剖析​

一、引言​ 在当今数字化时代&#xff0c;数据是企业和组织的核心资产之一。许多应用程序都依赖于数据库来存储和管理数据&#xff0c;而 Java 作为一种广泛使用的编程语言&#xff0c;常被用于开发与数据库交互的应用程序。然而&#xff0c;SQL 注入这一安全漏洞却如同隐藏在…

深度学习项目--分组卷积与ResNext网络实验探究(pytorch复现)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 ResNext是分组卷积的开始之作&#xff0c;这里本文将学习ResNext网络&#xff1b;本文复现了ResNext50神经网络&#xff0c;并用其进行了猴痘病分类实验…

CSS 笔记——Flexbox(弹性盒布局)

目录 1. Flex 容器与 Flex 项目 2. 主轴与交叉轴 3. Flex 容器的属性 display flex-direction justify-content align-items align-content flex-wrap 4. Flex 项目的属性 flex-grow flex-shrink flex-basis flex align-self 5. Flexbox 的优点 6. Flexbox 的…

cpp(c++)win 10编译GDAL、PROJ、SQLite3、curl、libtiff

cpp&#xff08;c&#xff09;编译GDAL、PROJ、SQLite3 Sqlite3libtiffcurlprojGDAL Sqlite3 1、下载 Sqlite3 源码、工具、二进制预编译 exe Sqlite3 官网&#xff1a;https://www.sqlite.org/download.html 下载 sqlite-amalgamation-3430200.zipsqlite-dll-win64-x64-3430…

每日一题(小白)暴力娱乐篇23

由题意得知给我们一串数字&#xff0c;我们每次交换两位&#xff0c;最少交换多少次成功得到有顺序的数组。我们以平常的思维去思考&#xff0c;加入给你一串数字获得最少的交换次数&#xff0c;意味着你的交换后续基本不会变&#xff0c;比如说2 1 3 5 4 中1与2交换后不变&…

01-Redis-基础

1 redis诞生历程 redis的作者笔名叫做antirez&#xff0c;2008年的时候他做了一个记录网站访问情况的系统&#xff0c;比如每天有多少个用户&#xff0c;多少个页面被浏览&#xff0c;访客的IP、操作系统、浏览器、使用的搜索关键词等等(跟百度统计、CNZZ功能一样)。最开始存储…

【从零开始学习JVM | 第一篇】快速认识JVM

什么是JVM&#xff1f; JVM--Java虚拟机&#xff0c;它是Java实现平台无关性的基石。 Java程序运行的时候&#xff0c;编译器将Java代码编译为平台无关的Java字节码文件&#xff08;.class&#xff09;&#xff0c;接下来对应平台的JVM对字节码进行运行解释&#xff0c;翻译成…

使用RabbitMQ实现异步秒杀

搭建RabbitMQ 在虚拟机上用docker搭建RabbitMQ&#xff0c;首先拉取镜像 docker run --privilegedtrue -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management mkdir -p /usr/local/docker/rabbitmq再创建rabbitmq容器&#xff0c;下面的命令已经能够创建之后…

解决华硕主板Z890m下载ubuntu20.04后没有以太网问题

问题描述&#xff1a; 华硕主板Z890m下载双系统ubuntu20.04后&#xff0c;发现ubuntu不能打开以太网。 问题原因&#xff1a; 华硕主板的网卡驱动是r8125,而ubuntu20.04的驱动版本是r8169&#xff0c;所以是网卡驱动不匹配造成 解决方案 开机界面按下F2进入BOIS模式&#…

xLua的Lua调用C#的2,3,4

使用Lua在Unity中创建游戏对象&#xff0c;组件&#xff1a; 相关代码如下&#xff1a; Lua --Lua实例化类 --C# Npc objnew Npc() --通过调用构造函数创建对象 local objCS.Npc() obj.HP100 print(obj.HP) local obj1CS.Npc("admin") print(obj1.Name)--表方法希…

Debian系统_主板作为路由器_测试局域网设备间网速

Debian系统_主板作为路由器_测试局域网设备间网速 一、360软件测网速 360测出来的网速实际上是宽带的速度&#xff0c;并不是路由器LAN口到电脑这一段的网速 二、使用iperf3 进行双向带宽测试 1、开发板端下载软件 //Debian系统或者/Ubuntu sudo apt update && sudo…

从 macos 切换到 windows 上安装的工具类软件

起因 用了很多年的macos, 已经习惯了macos上的操作, 期望能在windows上获得类似的体验, 于是花了一些时间来找windows上相对应的软件. 截图软件 snipaste​​​​​​ windows和macos都有的软件, 截图非常好用 文件同步软件 oneDrive: 尝试了不同的同步软件, 还是微软在各…

JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)

目录 JavaScript中通过array.map(&#xff09;实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等&#xff0c;array.map&#xff08;&#xff09;的使用详解&#xff08;附实际应用代码&#xff09; 一、什么时候该使用Array.map()&#xff0…

SQL优化技术分享:从 321 秒到 0.2 秒的性能飞跃 —— 基于 PawSQL 的 TPCH 查询优化实战

在数据库性能优化领域&#xff0c;TPC-H 测试集是一个经典的基准测试工具&#xff0c;常用于评估数据库系统的查询性能。本文将基于 TPCH 测试集中的第 20个查询&#xff0c;结合 PawSQL 自动化优化工具&#xff0c;详细分析如何通过 SQL 重写和索引设计&#xff0c;将查询性能…

密码学基础——DES算法

前面的密码学基础——密码学文章中介绍了密码学相关的概念&#xff0c;其中简要地对称密码体制(也叫单钥密码体制、秘密密钥体制&#xff09;进行了解释&#xff0c;我们可以知道单钥体制的加密密钥和解密密钥相同&#xff0c;单钥密码分为流密码和分组密码。 流密码&#xff0…

在 Linux 终端中轻松设置 Chromium 的 User-Agent:模拟手机模式与自定义浏览体验

在 Linux 系统中&#xff0c;通过终端灵活控制 Chromium 的行为可以大幅提升工作效率。本文将详细介绍如何通过命令行参数和环境变量自定义 Chromium 的 User-Agent&#xff0c;并结合手机模式模拟&#xff0c;实现更灵活的浏览体验。 为什么需要自定义 User-Agent&#xff1f;…

http页面的加载过程

HTTP/2 核心概念 1.1 流&#xff08;Stream&#xff09; • 定义&#xff1a;HTTP/2 连接中的逻辑通道&#xff0c;用于传输数据&#xff0c;每个流有唯一标识符&#xff08;Stream ID&#xff09;。 • 特点&#xff1a; ◦ 支持多路复用&#xff08;多个流并行传输&#…

MySQL【8.0.41版】安装详细教程--无需手动配置环境

一、MySQL 介绍 1. 概述 MySQL 是一个开源的关系型数据库管理系统&#xff0c;由瑞典公司 MySQL AB 开发&#xff0c;现属于 Oracle 旗下。它基于 SQL&#xff08;结构化查询语言&#xff09;进行数据管理&#xff0c;支持多用户、多线程操作&#xff0c;广泛应用于 Web 应用、…

鸿蒙ArkTS实战:从零打造智能表达式计算器(附状态管理+路由传参核心实现)

还在为组件状态混乱、页面跳转丢参数而头疼&#xff1f; 这篇博客将揭秘如何用鸿蒙ArkTS打造一个漂亮美观的智能计算器&#xff1a; ✅ 输入完整表达式&#xff0c;秒出结果——字符串切割简单计算 ✅ 状态管理黑科技——Provide/Consume 实现跨组件实时响应 ✅ 路由传参实战—…