【蓝桥杯】十五届省赛B组c++

news2025/4/19 3:46:53

目录

前言

握手问题

分析

排列组合写法

枚举

小球反弹

分析

代码

好数

分析

代码

R 格式

分析

代码

宝石组合

分析

代码

数字接龙

分析

代码

拔河

分析

代码

总结


前言

主播这两天做了一套蓝桥杯的省赛题目(切实感受到了自己有多菜)。


握手问题


分析

填空题的第一道,很简单,不过主播第一次错了(原因是把方案数的+想成了*,被自己蠢笑了)。

这道题如果有一些排列组合的基础的话应该很容易想到答案就是7加到49

但这不代表没有排列组合的基础就不会,依然可以写对这道题。(枚举)


排列组合写法

#include<iostream>
using namespace std;
int l;
​
int main()
{
    for(int i = 7; i <= 49; i++)
        l += i;
    cout << l;
}

枚举

#include<iostream>
using namespace std;
int l;
int main()
{
    for(int i = 1; i <= 50; i++)
        for(int j = i + 1; j <= 50; j++)
        {
            if(i <= 7 && j <= 7) continue; //选定七个人不握手
            l++;
        }
    cout << l;
}

小球反弹


分析

这道题主播依旧没有写出来()

物理题,首先将速度分解到xy两个方向,随后整个运动过程就可以看作在x轴上来回运动的同时y轴上来回运动

假设在x轴上经过a个来回y轴上经过b个来回回到原点,可得:
2ax/dx = 2by/dy

移项:
a/b = dx * y/ dy * x

随后我们对a / b进行约分,即:a / gcd(a, b), b / gcd(a, b)

随后再根据路程和速度即可得出:t = 2ax / dx

最后通过t * v求出路程。


代码

#include<iostream>
#include<cmath>
using namespace std;
int x = 343720, y = 233333;
int dx = 15, dy = 17;
​
int gcd(int a, int b)
{
    if(b == 0) return a;
    return gcd(b, a % b);
}
int main()
{
    int a = y * dx, b = x * dy;
    a /= gcd(a, b); //约分
    double t = 2.0 * a * x / dx; //时间
​
    printf("%.2lf", t * sqrt(dx * dx + dy * dy));
​
    return 0;
}

好数


分析

观察数据量——1e7枚举每一位的话最大是7 * 1e7,小于1e8所以直接暴力枚举计数即可。(这个主播最开始也是没有想到,去写模拟了)

代码

#include<iostream>
using namespace std;
int l, n;
​
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        int j = 1, k = i;
        l++;
        while(k)
        {
            if((j & 1) != (k & 1))
            {
                l--;
                break;
            }
            j++;
            k /= 10;
        }
    }
    printf("%d", l);
    return 0;
}

R 格式


分析

发现n很大d也很大,所以考虑高精度

这道题主要考察了对浮点数的高精度写法,可以在最开始忽略掉小数点,随后进行累乘(高精度 * 低精度)再最后手动进位(高精度 + 低精度)

主播最开始还去写了高精度*高精度QAQ,最后发现根本没必要,真是蠢到家了。


代码

#include<iostream>
#include <algorithm>
#include<vector>
using namespace std;
int n;
string l;
vector<int> A, B;
​
vector<int> cur(vector<int>& A, int b)
{
    int x = 0;
    vector<int> C;
    for(int i = 0; i < A.size(); i++)
    {
        x += A[i] * b;
        C.push_back(x % 10);
        x /= 10;
    }
    while(x)
    {
        C.push_back(x % 10);
        x /= 10;
    }
    return C;
}
​
vector<int> add(vector<int>& A, vector<int> B)
{
    int x = 0;
    vector<int> C;
    for(int i = 0; i < A.size() || i < B.size(); i++)
    {
        if(i < A.size()) x += A[i];
        if(i < B.size()) x += B[i];
        C.push_back(x % 10);
        x /= 10;
    }
    if(x) C.push_back(1);
    return C;
}
​
int main()
{
    cin >> n >> l;
    for(int i = l.size() - 1; i >= 0; i--)
    {
        if(l[i] == '.') continue;
        A.push_back(l[i] - '0'); //先不考虑小数点
    }
    
    for(int i = 1; i <= n; i++)
        A = cur(A, 2); //乘法计算.
    // 四舍五入
    int i = 0;
    for(; i < l.size(); i++)
        if(l[i] == '.') break; //找到小数点位置
​
    int x = 0;
    int d = l.size() - 1 - i; //小数部分
    
    reverse(A.rbegin(), A.rend()); //反转
    
    for(int k = 0; k < l.size() - 1 - i; k++)
    {
        x = A.back();
        A.pop_back();
    } //消除小数部分
    reverse(A.rbegin(), A.rend()); //反转
    if(x >= 5)
        A = add(A, {1}); //进位
    for(int i = A.size() - 1; i >= 0; i--)
        printf("%d", A[i]);
    return 0;
}

宝石组合


分析

题意很简单,这道题的主要难点就在于公式的推导。
S = H_aH_bH_c * LCM(H_a, H_b, H_c) / (LCM(H_a, H_b)*LCM(H_a, H_c)*LCM(H_b,H_c))

公式的推导有两种方法,因为主播目前只熟悉一种所以就按照这个思路来讲了。

公式推导基于算数基本定理

我们将每一项进行质因数分解可得到
H_a = p_1^{c_1} * p_2^{c_2} * ... p_n^{c_n}

同理将Hb于Hc分解质因数可得
H_a = p_1^{e_1} * p_2^{e_2} * ... p_n^{e_n}
H_a = p_1^{d_1} * p_2^{d_2} * ... p_n^{d_n}

我们按照质数进行因式分解,取出其中的一项可得:
p_1^{c_1} * p_1^{d_1} * p_1^{e_1} * p_1^{max(c_1, d_1, e_1)} / (p_1^{max(c_1, d_1)} * p_1^{max(c_1, e_1)} * p_1^{max(d_1, e_1)})

随后我们消掉maxmin函数,设c1 > d1 > e1,可得:
p^{e_1}


e_1 = min(c_1, d_1, e_1)

满足最大公因数的条件,我们最后将公式整合可得:
S = gcd(H_a, H_b, H_c)

至此我们完成了本道题的第一步

随后我们来查找max(gcd(Ha, Hb, Hc))

显然对于本道题直接枚举的话会超时,如何来做呢?

可以发现H很小且gcd < H,所以我们可以直接枚举约数


代码

#include<iostream>
using namespace std;
const int N = 100010;
int n;
int a[N];
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        int x; scanf("%d", &x);
        a[x]++; //存储出现次数
    }
    for(int i = N - 1; i; i--)           
    {
        int l = 0;
        for(int j = i; j < N; j += i)
            l += a[j];
        if(l >= 3)
        {
            l = 0;
            for(int j = i; j < N && l < 3; j += i)
                for(int k = 0; k < a[j] && l < 3; k++, l++)
                    printf("%d ", j);
            break;
        }
    }
    return 0;
}

数字接龙


分析

发现数据量很小所以直接搜索就好。

对于本道题的一个细节是如何判断交叉

主播的建议是存储一个这样的值:read[x + dx][y + dy]

数组内的两个参数是起始坐标终止坐标

这样写为什么是正确的呢?

因为只有斜着走的时候才有可能出现交叉的情况,所以每个方向的步长都是1

很容易发现两个方向是一个奇数和一个偶数,和一定是一个奇数,而若将一个奇数分解为两个相差为1的数字只有两种情况(交换位置)。对于本道题来说正合适。所以写一个这样的数组就可以避免交叉。


代码

#include <iostream>
#include <cstring>
#include <vector>
#define s second
#define f first
using namespace std;
typedef pair<int, int> PII;
const int N = 15;
int n, p;
int map[N][N];
vector<int> to[N][N]; //存储能够到达哪个点,显著降低时间复杂度的小小小优化。
bool read[N][N];
bool cun[2 * N][2 * N]; //防止交叉
vector<int> vtr;
PII s[] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; //八个方向
​
bool dfs(int x, int y, int k)
{
    if(x == n && y == n && vtr.size() == n * n - 1)
    {
        for(int i = 0; i < vtr.size(); i++)
            printf("%d", vtr[i]);
        return true;
    }
    if(x == n && y == n) return false;
    for(int i : to[x][y])
    {
        int dx = x + s[i].f, dy = y + s[i].s;
        if(read[dx][dy] == false) //第一层筛选
        {
            if(i & 1 == 0 || cun[x + dx][y + dy] == false) //无交叉
            {
                read[dx][dy] = true;
                if(i & 1) cun[x + dx][y + dy] = true;
                vtr.push_back(i);
                if(dfs(dx, dy, (k + 1) % p))
                    return true;
                vtr.pop_back();
                if(i & 1) cun[x + dx][y + dy] = false;
                read[dx][dy] = false;
            }
        }
    }
    return false;
}
​
int main()
{
    memset(map, 0x3f, sizeof map);
    scanf("%d%d", &n, &p);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            scanf("%d", &map[i][j]);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            for(int k = 0; k < 8; k++)
            {
                int dx = i + s[k].f, dy = j + s[k].s;
                if(map[dx][dy] == (map[i][j] + 1) % p)
                    to[i][j].push_back(k); 
            }
    read[1][1] = true;
    if(!dfs(1, 1, 1))
        printf("-1");
    return 0;
}

拔河


分析

最开始以为是dp但是后来发现我想多了。

题目要求两个不相交的区间的差值最小,可以发现无论两个区间又无相交情况差值都是不变的,所以问题就转化成了差值最小的区间问题

套用模板——首先求出所有区间的和,随后sort之后差值最小的必然会在相邻的两个区间上产生。当然对于本题需要考虑结果是否合法,即:一个区间不可以完全包含另一个区间。(使用区间取交集模板即可)


代码

#include<iostream>
#include<vector>
#include<algorithm>
#define s second
#define f first
using namespace std;
typedef long long LL;
​
typedef pair<LL, pair<int, int>> PIII;
using namespace std;
const int N = 2010;
int n;
LL s[N];
vector<PIII> vtr; 
​
bool cmp(pair<int, int> A, pair<int, int> B)
{
    int x = max(A.f, B.f);
    int y = min(A.s, B.s); //查看有没有交集
    return x == A.f && y == A.s || x == B.f && y == B.s;
}
​
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%lld", s + i);
    
        s[i] += s[i - 1];
    }
    LL cnt = 0x3f3f3f3f3f3f3f3f;
    for(int i = 1; i <= n; i++)
        for(int j = i; j <= n; j++)
            vtr.push_back({s[j] -  s[i - 1], {i, j}});
    sort(vtr.begin(), vtr.end());
    for(int i = 1; i < vtr.size(); i++)
        if(!cmp(vtr[i].s, vtr[i - 1].s))
            cnt = min(cnt, vtr[i].f - vtr[i - 1].f);
    printf("%lld", cnt);
    return 0;
}

总结

最后附上ak截图

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

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

相关文章

[Linux系统编程]多线程

多线程 1. 线程1.1 线程的概念1.2 进程与线程对比1.3 轻量级进程 2. Linux线程控制2.1 POSIX 线程&#xff08;pthread&#xff09;2.2 线程ID、pthread_t、和进程地址空间的关系2.2.1 pthread_self2.2.2 pthread_create2.2.3 pthread_join2.2.4 线程终止的三种方式2.2.5 pthre…

IntelliJ IDEA下开发FPGA——FPGA开发体验提升__下

前言 由于Quartus写代码比较费劲&#xff0c;虽然新版已经有了代码补全&#xff0c;但体验上还有所欠缺。于是使用VS Code开发&#xff0c;效果如下所示&#xff0c;代码样式和基本的代码补全已经可以满足开发&#xff0c;其余工作则交由Quartus完成 但VS Code的自带的git功能&…

odo18实施——销售-仓库-采购-制造-制造外包-整个流程自动化单据功能的演示教程

安装模块 安装销售 、库存、采购、制造模块 2.开启外包功能 在进入制造应用点击 配置—>设置 勾选外包&#xff0c;点击保存 添加信息 一、添加客户信息 点击到销售应用 点击订单—>客户 点击新建 创建客户1&#xff0c;及其他客户相关信息&#xff0c;点…

微信小程序生成某个具体页面的二维码

微信小程序&#xff0c;如果要生成某个具体页面&#xff0c;而非首页的二维码&#xff0c;体验和正式的生成方法如下&#xff1a; 1、体验版二维码&#xff1a; 管理---版本管理---修改页面路径&#xff0c;输入具体页面的路径以及参数&#xff0c;生成的是二维码 2、正式小程…

鸿蒙开发_ARKTS快速入门_语法说明_组件声明_组件手册查看---纯血鸿蒙HarmonyOS5.0工作笔记010

然后我们来看如何使用组件 可以看到组件的组成 可以看到我们使用的组件 然后看一下组件的语法.组件中可以使用子组件. 然后组件中可以有参数,来修改组件的样式等 可以看到{},这种方式可以设置组件参数,当然在下面. 的方式也可以的 然后再来

接口异常数组基础题

题目描述 设想你正在构建一个智能家居控制系统。这个系统可以连接多种不同类型的智能设备&#xff0c;如智能灯泡、智能空调和智能门锁。每种设备都有其独特的功能&#xff0c;不过它们也有一些通用的操作&#xff0c;像开启、关闭和获取设备状态等。系统需要提供一个方法来控…

rustdesk折腾手记

背景 我的工作环境&#xff1a;主力电脑是macPro, 另外一台ThinkPad W530作为开发机&#xff0c;装的是LinuxMint&#xff0c;还有一台ThinkPad P15作为服务器。平常显示器接到macPro&#xff0c;在macOS上通过微软的远程桌面连接到另外两台Linux。基本访问比较流畅&#xff0…

使用el-tab 实现两个tab切换

1、主页面 index.vue 2、tab1&#xff1a;school.vue 3、tab2&#xff1a;parent.vue 具体代码如下&#xff1a; <template><div class"app-container"><!-- 使用el-tabs 实现两个组件的切换 --><el-tabs v-model"activeName" typ…

使用Pholcus编写Go爬虫示例

想用Pholcus库来写一个Go的爬虫程序。首先&#xff0c;我得确认Pholcus的当前状态&#xff0c;因为之前听说过它可能已经不再维护了。不过用户可能还是需要基于这个库的示例&#xff0c;所以得先提供一个基本的框架。 首先&#xff0c;我应该回忆一下Pholcus的基本用法。Pholc…

单片机实现触摸按钮执行自定义任务组件

触摸按钮执行自定义任务组件 项目简介 本项目基于RT8H8K001开发板 RT6809CNN01开发板 TFT显示屏(1024x600) GT911触摸屏实现了一个多功能触摸按钮组件。系统具备按钮控制后执行任务的功能&#xff0c;可用于各类触摸屏人机交互场景。 硬件平台 MCU: STC8H8K64U&#xff0…

Ai云防护技术解析——服务器数据安全的智能防御体系

本文深度解析AI云防护技术如何通过智能流量分析、动态行为建模、自适应防御策略构建服务器安全体系。结合2023年群联科技实战案例,揭示机器学习算法在识别新型DDoS攻击、加密流量检测、零日漏洞防御中的技术突破,并附Gartner最新防护效果验证数据。 AI驱动的流量特征建模技术…

JSONP跨域访问漏洞

一、漏洞一:利用回调GetCookie <?php$conn new mysqli(127.0.0.1,root,root,learn) or die("数据库连接不成功"); $conn->set_charset(utf8); $sql "select articleid,author,viewcount,creattime from learn3 where articleid < 5"; $result…

图形裁剪算法

1.学习目标 理解区域编码(Region Code&#xff0c;RC) 设计Cohen-Sutherland直线裁剪算法 编程实现Cohen-Sutherland直线裁剪算法 2.具体代码 1.具体算法 /*** Cohen-Sutherland直线裁剪算法 - 优化版* author AI Assistant* license MIT*/// 区域编码常量 - 使用对象枚举…

R 语言科研绘图第 36 期 --- 饼状图-基础

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

vue 3 从零开始到掌握

vue3从零开始一篇文章带你学习 升级vue CLI 使用命令 ## 查看vue/cli版本&#xff0c;确保vue/cli版本在4.5.0以上 vue --version ## 安装或者升级你的vue/cli npm install -g vue/cli ## 创建 vue create vue_test ## 启动 cd vue_test npm run servenvm管理node版本&#…

【R语言绘图】圈图绘制代码

绘制代码 rm(list ls())# 加载必要包 library(data.table) library(circlize) library(ComplexHeatmap) library(rtracklayer) library(GenomicRanges) library(BSgenome) library(GenomicFeatures) library(dplyr)### 数据准备阶段 ### # 1. 读取染色体长度信息 df <- re…

Python爬虫第6节-requests库的基本用法

目录 前言 一、准备工作 二、实例引入 三、GET请求 3.1 基本示例 3.2 抓取网页 3.3 抓取二进制数据 3.4 添加headers 四、POST请求 五、响应 前言 前面我们学习了urllib的基础使用方法。不过&#xff0c;urllib在实际应用中存在一些不便之处。以网页验证和Cookies处理…

什么是可靠性工程师?

一、什么是可靠性工程师&#xff1f; 可靠性工程师就是负责确保产品在使用过程中不出故障、不给客户添麻烦。 你可以理解为是那种“挑毛病的人”&#xff0c;但不是事后挑&#xff0c;是提前想清楚产品在哪些情况下可能会出问题&#xff0c;然后解决掉。 比如&#xff1a; …

如何根据设计稿进行移动端适配:全面详解

如何根据设计稿进行移动端适配&#xff1a;全面详解 文章目录 如何根据设计稿进行移动端适配&#xff1a;全面详解1. **理解设计稿**1.1 设计稿的尺寸1.2 设计稿的单位 2. **移动端适配的核心技术**2.1 使用 viewport 元标签2.1.1 代码示例2.1.2 参数说明 2.2 使用相对单位2.2.…

【Kafka基础】Kafka 2.8以下版本的安装与配置指南:传统ZooKeeper依赖版详解

对于仍在使用Kafka 2.8之前版本的团队来说&#xff0c;需要特别注意其强依赖外部ZooKeeper的特性。本文将完整演示传统架构下的安装流程&#xff0c;并对比新旧版本差异。 1 版本特性差异说明 1.1 2.8 vs 2.8-核心区别 特性 2.8版本 2.8-版本 协调服务 可选内置KRaft模式 …