C/C++蓝桥杯算法真题打卡(Day4)

news2025/3/9 17:09:44

一、P11041 [蓝桥杯 2024 省 Java B] 报数游戏 - 洛谷

算法代码:

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

// 计算第 n 个满足条件的数
long long findNthNumber(long long n) {
    long long low = 1, high = 1e18; // 二分查找范围
    while (low < high) {
        long long mid = (low + high) / 2;
        // 计算 mid 以内 20 或 24 的倍数的个数
        long long count = mid / 20 + mid / 24 - mid / 120;
        if (count < n) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }
    return low;
}

int main() {
    long long n = 202420242024;
    long long result = findNthNumber(n);
    cout << result << endl;
    return 0;
}

代码说明

  1. 二分查找

    • 通过二分查找确定第 n 个满足条件的数。

    • 查找范围从 1 到 1e18(足够大的数)。

  2. 容斥原理

    • mid / 20:计算 mid 以内 20 的倍数的个数。

    • mid / 24:计算 mid 以内 24 的倍数的个数。

    • mid / 120:减去 20 和 24 的最小公倍数的个数(避免重复计算)。

  3. 时间复杂度

    • 二分查找的时间复杂度为 O(log N),效率非常高。

二、P8792 [蓝桥杯 2022 国 A] 最大公约数 - 洛谷

算法代码: 

#include<bits/stdc++.h>
#define int long long
#define lc 2*k
#define rc 2*k+1
using namespace std;
int n,a[1234567],cnt;
struct nord{
	int l,r,mx;
}t[1234567];
void build(int k,int l,int r){//建树
	t[k].l=l,t[k].r=r;
	if (l==r){
		t[k].mx=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(lc,l,mid);
	build(rc,mid+1,r);
	t[k].mx=__gcd(t[lc].mx,t[rc].mx);
}
int ask(int k,int l,int r){//求区间gcd
	if (l<=t[k].l&&r>=t[k].r) return t[k].mx;
	int ans=0;
	int mid=(t[k].l+t[k].r)/2;
	if (l<=mid) ans=__gcd(ans,ask(lc,l,r));
	if (r>mid) ans=__gcd(ans,ask(rc,l,r));
	return ans;
}
main(){
	cin>>n;
	for (int i=1;i<=n;i++) cin>>a[i],cnt+=(a[i]==1?1:0);
	build(1,1,n);
	if (cnt){//特殊情况
		cout <<n-cnt;
		return 0;
	}
	int ans=1e9;
	int i=1;
	for (int j=1;j<=n;j++){//枚举
		while (i<j&&ask(1,i+1,j)==1) i++;//一直往前走
		if (ask(1,i,j)==1) ans=min(ans,j-i);//成功了
	}
	if (ans==1e9) cout <<-1;//不合法
	else cout <<n+ans-1;
    return 0;
}

        这段代码的主要功能是解决一个与区间 GCD(最大公约数)相关的问题。以下是代码的思路和逻辑分析:


代码思路

1. 问题描述

  • 给定一个长度为 n 的数组 a

  • 目标是找到一个最短的区间 [i, j],使得该区间内所有元素的 GCD 为 1。

  • 如果存在这样的区间,输出将整个数组变为全 1 的最小操作次数;否则输出 -1。

2. 核心逻辑

  • 特殊情况处理

    • 如果数组中已经有 cnt 个 1,则直接输出 n - cnt,因为只需要将其他元素变为 1 即可。

  • 区间 GCD 计算

    • 使用线段树维护区间 GCD,支持快速查询任意区间的 GCD。

  • 滑动窗口枚举

    • 使用双指针 i 和 j 枚举区间 [i, j]

    • 如果区间 [i, j] 的 GCD 为 1,则尝试缩小窗口(移动 i)以找到更短的区间。

    • 记录满足条件的最短区间长度。

  • 结果计算

    • 如果找到满足条件的区间,输出 n + ans - 1(将整个数组变为全 1 的最小操作次数)。

    • 否则输出 -1。


代码逻辑分析

1. 线段树构建

  • build 函数用于构建线段树,每个节点存储区间的左右边界和区间 GCD。

  • 递归地将数组划分为左右子区间,直到区间长度为 1。

  • 区间 GCD 通过 __gcd 函数计算。

2. 区间 GCD 查询

  • ask 函数用于查询区间 [l, r] 的 GCD。

  • 如果当前节点区间完全包含在查询区间内,则直接返回节点值。

  • 否则递归查询左右子区间,并计算 GCD。

3. 滑动窗口枚举

  • 使用双指针 i 和 j 枚举区间。

  • 如果区间 [i, j] 的 GCD 为 1,则尝试缩小窗口(移动 i)。

  • 记录满足条件的最短区间长度 ans

4. 结果计算

  • 如果找到满足条件的区间,输出 n + ans - 1

  • 否则输出 -1。


代码优化建议

  1. 变量命名

    • 变量名如 lcrcnord 等不够直观,建议改为更具描述性的名称,如 left_childright_childNode 等。

  2. 代码可读性

    • 添加注释,解释关键逻辑和变量的含义。

    • 使用空格和换行符提高代码的可读性。

  3. 边界条件处理

    • 确保数组下标从 1 开始,避免越界问题。

    • 在滑动窗口枚举时,注意 i 和 j 的移动条件。

  4. 时间复杂度

    • 线段树构建的时间复杂度为 O(n)。

    • 区间查询的时间复杂度为 O(log n)。

    • 滑动窗口枚举的时间复杂度为 O(n log n)。

    • 总体时间复杂度为 O(n log n),效率较高。


修正后的代码

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

const int MAXN = 1234567;
int n, a[MAXN], cnt;

struct Node {
    int l, r, mx;
} t[MAXN * 4];

// 构建线段树
void build(int k, int l, int r) {
    t[k].l = l, t[k].r = r;
    if (l == r) {
        t[k].mx = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(2 * k, l, mid);
    build(2 * k + 1, mid + 1, r);
    t[k].mx = __gcd(t[2 * k].mx, t[2 * k + 1].mx);
}

// 查询区间 GCD
int ask(int k, int l, int r) {
    if (l <= t[k].l && r >= t[k].r) return t[k].mx;
    int ans = 0;
    int mid = (t[k].l + t[k].r) / 2;
    if (l <= mid) ans = __gcd(ans, ask(2 * k, l, r));
    if (r > mid) ans = __gcd(ans, ask(2 * k + 1, l, r));
    return ans;
}

signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        cnt += (a[i] == 1 ? 1 : 0);
    }

    build(1, 1, n);

    // 特殊情况:数组中已经有 1
    if (cnt) {
        cout << n - cnt << endl;
        return 0;
    }

    int ans = 1e9;
    int i = 1;

    // 滑动窗口枚举
    for (int j = 1; j <= n; j++) {
        while (i < j && ask(1, i + 1, j) == 1) i++;
        if (ask(1, i, j) == 1) ans = min(ans, j - i + 1);
    }

    // 输出结果
    if (ans == 1e9) cout << -1 << endl;
    else cout << n + ans - 1 << endl;

    return 0;
}

总结

        这段代码通过线段树和滑动窗口的结合,高效地解决了区间 GCD 问题。修正后的代码提高了可读性和健壮性,同时保留了原有的高效逻辑。

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

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

相关文章

C++编写Redis客户端

目录 安装redis-plus-plus库 ​编辑 编译Credis客户端 redis的通用命令使用 get/set exists del keys expire /ttl type string类型核心操作 set和get set带有超时时间 set带有NX string带有XX mset mget getrange和setrange incr和decr list类型核心操作…

记录一下Django的密码重置(忘记密码)

一. Django默认的密码重置 1.路由 # url.pyfrom django.contrib.auth import views as auth_viewsurlpatterns [# 密码重置path(password_reset/, auth_views.PasswordResetView.as_view(), namepassword_reset),# 用户输入邮箱后&#xff0c;跳转到此页面path(password_res…

【运维篇】KubeSphere-02(经验汇总)

一、使用建议 1.对于数据库、对像存储比较重的要不能丢失&#xff0c;有异地存储备份需求的有状态服务&#xff0c;不建议采用k8s进行部署&#xff0c;会导致运维难度更大。 2.对于中间件如redis、MQ、harbor、seata、nacos、zookeeper可采用k8s部署。 3.对于无状态服务tomc…

Qt:多线程

目录 初识Qt多线程 QThread常用API QThread的使用 Qt中的锁 条件变量和信号量 初识Qt多线程 Qt 多线程 和 Linux 中的线程本质是一个东西 Linux 中学过的 多线程 APl&#xff0c;Linux 系统提供的 pthread 库 Qt 中针对系统提供的线程 API 重新封装了 C11 中&#xff0c;…

算法系列之广度优先搜索解决妖怪和尚过河问题

在算法学习中&#xff0c;广度优先搜索&#xff08;BFS&#xff09;是一种常用的图搜索算法&#xff0c;适用于解决最短路径问题、状态转换问题等。本文将介绍如何利用广度优先搜索解决经典的“妖怪和尚过河问题”。 问题描述 有三个妖怪和三个和尚需要过河。他们只有一条小船…

详解常用集合和映射中的线程安全问题

1. 前言 在 Java 中&#xff0c;集合和映射是常用的数据结构&#xff0c;它们分为线程安全和线程不安全两类。我们常用的集合包括&#xff1a;ArrayList、HashSet、CopyOnWriteArrayList、CopyOnWriteArraySet。常用的映射包括&#xff1a;HashMap、ConcurrentHashMap、Hashta…

计算机毕业设计SpringBoot+Vue.js车辆管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

【js逆向】iwencai国内某金融网站实战

地址&#xff1a;aHR0cHM6Ly93d3cuaXdlbmNhaS5jb20vdW5pZmllZHdhcC9ob21lL2luZGV4 在搜索框中随便输入关键词 查看请求标头&#xff0c;请求头中有一个特殊的 Hexin-V,它是加密过的&#xff1b;响应数据包中全是明文。搞清楚Hexin-V的值是怎么生成的&#xff0c;这个值和cooki…

【音视频 | AAC】AAC编码库faac介绍、使用步骤、例子代码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

Unity摄像机跟随物体

功能描述 实现摄像机跟随物体&#xff0c;并使物体始终保持在画面中心位置。 实现步骤 创建脚本&#xff1a;在Unity中创建一个新的C#脚本&#xff0c;命名为CameraFollow。 代码如下&#xff1a; using UnityEngine;public class CameraFollow : MonoBehaviour {public Tran…

dp_走方格(包含dfs分析,记忆化搜索)

类似题目解析&#xff1a;dp_最长上升子序列&#xff08;包含dfs分析&#xff0c;记忆化搜索&#xff09;-CSDN博客 题目链接&#xff1a;2067. 走方格 - AcWing题库 题目图片&#xff1a; 分析题目&#xff08;dfs&#xff09; 这个题目说有一个行为n行&#xff0c;列为m列…

如何用Kimi生成PPT?秒出PPT更高效!

做PPT是不是总是让你头疼&#xff1f;&#x1f629; 快速制作出专业的PPT&#xff0c;今天我们要推荐两款超级好用的AI工具——Kimi 和 秒出PPT&#xff01;我们来看看哪一款更适合你吧&#xff01;&#x1f680; &#x1f947; Kimi&#xff1a;让PPT制作更轻松 Kimi的生成效…

K8S学习之基础十八:k8s的灰度发布和金丝雀部署

灰度发布 逐步扩大新版本的发布范围&#xff0c;从少量用户逐步扩展到全体用户。 特点是分阶段发布、持续监控、逐步扩展 适合需要逐步验证和降低风险的更新 金丝雀部署 将新版本先部署到一小部分用户或服务器&#xff0c;观察其表现&#xff0c;再决定是否全面推广。 特点&…

Java 深度复制对象:从基础到实战

目录 一、深度复制的概念二、实现深度复制的方法1. 使用序列化2. 手动实现深度复制 三、总结 在 Java 编程中&#xff0c;对象的复制是一个常见的需求。然而&#xff0c;简单的复制操作&#xff08;如直接赋值&#xff09;只会复制对象的引用&#xff0c;而不是创建一个新的对象…

【前端】webstorm创建一个导航页面:HTML、CSS 和 JavaScript 的结合

文章目录 前言一、项目结构二、HTML 结构三、CSS 样式四、JavaScript 功能五、现代化风格优化htmlcssjavascript运行效果 总结 前言 在现代网页开发中&#xff0c;一个良好的导航栏是提升用户体验的重要组成部分。在这篇文章中&#xff0c;我将向您展示如何创建一个简单而完整…

AI编程: 一个案例对比CPU和GPU在深度学习方面的性能差异

背景 字节跳动正式发布中国首个AI原生集成开发环境工具&#xff08;AI IDE&#xff09;——AI编程工具Trae国内版。 该工具模型搭载doubao-1.5-pro&#xff0c;支持切换满血版DeepSeek R1&V3&#xff0c; 可以帮助各阶段开发者与AI流畅协作&#xff0c;更快、更高质量地完…

第11章 web应用程序安全(网络安全防御实战--蓝军武器库)

网络安全防御实战--蓝军武器库是2020年出版的&#xff0c;已经过去3年时间了&#xff0c;最近利用闲暇时间&#xff0c;抓紧吸收&#xff0c;总的来说&#xff0c;第11章开始学习利用web应用程序安全&#xff0c;主要讲信息收集、dns以及burpsuite&#xff0c;现在的资产测绘也…

GitHub上传项目

总结&#xff08;有基础的话直接执行这几步&#xff0c;就不需要再往下看了&#xff09;&#xff1a; git init 修改git的config文件&#xff1a;添加:[user]:name你的github用户名 email你注册github的用户名 git branch -m master main git remote add origin 你的URL gi…

DIY Tomcat:手写一个简易Servlet容器

在Java Web开发领域&#xff0c;Tomcat堪称经典&#xff0c;它作为Servlet容器&#xff0c;承载着无数Web应用的运行。今天&#xff0c;我将带大家一同探索如何手写一个简易的Tomcat&#xff0c;深入理解其底层原理。 一、背景知识 在开始之前&#xff0c;我们需要对几个关键…

基于ssm的物资进销存(全套)

现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本货物进销管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&#…