跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

算法实战进阶:预处理、滑动窗口、前缀和与图论并查集应用

涵盖模拟优化、并查集连通性分析及动态规划等核心算法技巧。通过具体题目演示如何从暴力枚举转向高效解法,重点讲解预处理降低复杂度、利用同余性质优化空间以及逆向思维在图遍历中的应用。适合备战蓝桥杯及各类算法竞赛,帮助读者巩固基础模板并提升解题思路。

SecGuard发布于 2026/3/15更新于 2026/10/2179 浏览
算法实战进阶:预处理、滑动窗口、前缀和与图论并查集应用

前言

这些题目摘录自洛谷,均为典型算法题,适合用于蓝桥杯及各类竞赛备战。通过练习可以锻炼解题思路,从掌握算法模板过渡到具体题目的分析与运用。

本期涉及的核心算法包括:模拟优化、图的性质与并查集、暴力枚举结合预处理与滑动窗口、线性 DP、前缀和结合哈希表与同余性质、以及正难则反的逆向图思维。

1. 寻宝

题目链接: P1076 [NOIP 2012 普及组] 寻宝

寻宝示意图

解法:模拟 + 优化

根据题意直接模拟爬楼过程是可行的,但如果每层楼都遍历寻找楼梯房间,时间复杂度会较高。我们可以进行优化:

使用 cnt[i] 数组记录第 i 层楼有楼梯的房间总数。当需要找第 s 个符合要求的房间时,利用取模运算 s % cnt[i] 即可定位。需要注意的是,如果取模结果为 0,实际上对应的是该层的第 cnt[i] 个房间。

代码实现

#include <iostream>
using namespace std;

typedef long long LL;
const int N = 1e4 + 10, M = 110, MOD = 20123;

LL n, m;
bool st[N][N]; // 标记楼梯信息
LL s[N][M];    // 维护指示牌信息
LL cnt[N];     // 用于优化,存第 i 楼有楼梯的房间个数

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < m; j++) {
             a, b;
            cin >> a >> b;
             (a) {
                st[i][j] = ;
                cnt[i]++;
            }
            s[i][j] = b;
        }
    }

     pos = ;
    cin >> pos;
    LL ret = ;

     ( i = ; i <= n; i++) {
        ret = (ret + s[i][pos]) % MOD;
        
        
        LL step = s[i][pos] % cnt[i];
         (!step) step = cnt[i];

         () {
             (st[i][pos]) step--;
             (step == ) ;
            pos++;
             (pos == m) pos = ; 
        }
    }

    cout << ret << endl;
     ;
}
int
if
true
int
0
0
for
int
1
// 优化逻辑:计算当前层需要走的步数
if
while
1
if
if
0
break
if
0
// 走了一圈回到开头
return
0

2. 村村通

题目链接: P1536 村村通

村村通示意图

解法:图的性质 + 并查集

这道题的目标是将已经连接好的部分城镇和未连接的城镇全部连通(可以是间接连接)。根据图论性质,若一个无向图有 k 个连通块,使其连通所需的最少边数为 k - 1。

因此,我们只需要用并查集统计当前的连通块数量,结果即为答案。输入包含多组数据,通常以文件结束符(Ctrl+Z)作为终止条件。

代码实现

#include <iostream>
using namespace std;

const int N = 1010;
int n, m;
int fa[N];

// 查找根节点,带路径压缩
int find(int x) {
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}

// 合并集合
void unite(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    if (rootX != rootY) {
        fa[rootX] = rootY;
    }
}

int main() {
    // 处理多组数据,cin 返回 false 表示遇到 EOF (Ctrl+Z)
    while (cin >> n >> m && (n || m)) {
        for (int i = 1; i <= n; i++) fa[i] = i;

        for (int i = 0; i < m; i++) {
            int u, v;
            cin >> u >> v;
            unite(u, v);
        }

        int components = 0;
        for (int i = 1; i <= n; i++) {
            if (fa[i] == i) components++;
        }

        // 需要的边数 = 连通块数 - 1
        cout << components - 1 << endl;
    }
    return 0;
}

提示: 实际做题时,注意边界情况,例如 n=1 时不需要任何边。

目录

  1. 前言
  2. 1. 寻宝
  3. 解法:模拟 + 优化
  4. 代码实现
  5. 2. 村村通
  6. 解法:图的性质 + 并查集
  7. 代码实现

更多推荐文章

查看全部
  • 多模态大模型综述:从基础模型到智能代理
  • 近五年微/纳米机器人赋能肿瘤精准治疗综述:聚焦 GBM
  • C++ 拷贝构造函数与赋值运算符重载详解
  • 基于 AI Ping 的大模型 API 统一接入与成本优化实践
  • C 语言初阶数据结构习题(二)
  • Spring Bean 作用域、生命周期与自动装配源码解析
  • Go Web 开发:网络通信、Socket 与数据库实战
  • Django Web 框架入门与核心使用
  • 基于 GFPGAN 的低质量人脸图像超分辨率恢复实战
  • 91n 边缘计算设备部署轻量 TensorFlow 模型全流程
  • AI Agent 框架:工作流与 Agent 运行时模块设计
  • Dify 接入企业微信群聊机器人配置与实现指南
  • 利用 Fiddler 代理抓包 JVM 发出的 HTTP 请求
  • 基于 Retinaface 与 CurricularFace 的人脸身份核验方案
  • 基于 PSO-DWA 融合的无人机三维动态避障路径规划及 Matlab 实现
  • C++ 函数重载:核心规则、匹配机制与实战
  • Java 集合框架核心:List、Set 与 Map 的差异解析
  • Python 实战:构建文档总结、代码生成与智能检索助手
  • PentAGI 基于 Docker 的 AI 自动化渗透环境部署指南
  • DeepSeek 深度使用指南:提示词技巧与本地知识库搭建

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online