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

算法实战:预处理、滑窗、前缀和哈希与图论并查集

洛谷精选算法题,涵盖寻宝模拟优化、村村通并查集连通块计算等核心考点。通过具体代码解析预处理、滑动窗口、前缀和哈希及图论技巧,帮助读者掌握竞赛常见解题思路,提升编码实战能力。重点讲解如何利用数学规律减少循环次数,以及并查集在连通性问题中的应用。

DevOpsTeam发布于 2026/3/15更新于 2026/10/1269 浏览
算法实战:预处理、滑窗、前缀和哈希与图论并查集

这些题目摘录自洛谷,属于典型竞赛题,涵盖模拟优化、图论性质、暴力枚举及动态规划等核心考点。通过练习这些题目,可以有效锻炼解题思路,将算法模板转化为实际代码能力。

本期涉及算法:模拟 + 优化,图的性质 + 并查集,暴力枚举 + 预处理 + 滑动窗口(优化),线性 dp,前缀和 + 哈希表 + 同余,正难则反 - 反图。

1. 寻宝

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

解法:模拟 + 优化

根据题意模拟爬楼过程。如果每层楼都遍历所有房间去找楼梯,时间复杂度会很高。我们可以用 cnt[i] 数组记录第 i 层楼有楼梯的房间数。对于要找的第 s 个楼梯,直接计算 s % cnt[i] 即可定位。注意取模结果为 0 时,应指向该层的最后一个符合条件的房间。

代码:

#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++) { // 注意:房间编号从 0 开始
            int a, b;
            cin >> a >> b;
            if (a) {
                st[i][j] = true;
                cnt[i]++;
            }
            s[i][j] = b;
        }
    }

    int pos = 0;
    cin >> pos;
    LL ret = 0;

    for (int i = 1; i <= n; i++) {
        ret = (ret + s[i][pos]) % MOD; // 累加楼层数值
        
        // 优化:直接计算目标位置
        LL step = s[i][pos] % cnt[i];
        if (!step) step = cnt[i]; // 取模为 0 时对应最后一个
        
        while (1) {
            if (st[i][pos]) step--;
            if (step == 0) break;
            pos++;
            if (pos == m) pos = 0; // 走了一圈回到开头
        }
    }

    cout << ret << endl;
    return 0;
}

2. 村村通

题目:P1536 村村通

解法:图的性质 + 并查集

这道题的核心在于连通性。要将已经连接好的部分城镇和未连接的城镇全部连通,所需的最少边数等于 连通块的个数 - 1。因此,我们使用并查集来维护当前连通的点集。

输入可能包含多组数据,通常以 Ctrl+Z 结束输入。在实现时,记得初始化并查集结构。

代码:

#include <iostream>
using namespace std;

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

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

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

int main() {
    while (cin >> n >> m && n != 0) { // 处理多组数据
        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++;
        }

        cout << components - 1 << endl;
    }
    return 0;
}

以上题目适合蓝桥杯及各类算法比赛备战。建议在实际编码中多尝试不同的边界条件,加深理解。

目录

  1. 1. 寻宝
  2. 2. 村村通

更多推荐文章

查看全部
  • 智能车摄像头控制:动态权、模糊 PID、速度决策与路径优化
  • ESP32S3 小智 AI 接入音乐 API 实现网络音频流播放
  • 无人机“黑飞”正式入法:2026年1月1日起违规飞行将面临拘留
  • AI Agent 框架选型指南:OpenClaw、LangChain、AutoGPT、CrewAI 深度对比
  • Spark 核心基础与架构全解析
  • python-docx-template 模板化生成 Word 文档指南
  • 从二叉搜索树到 STL:set 容器的本质与用法
  • 算法优选:位运算实战技巧与题解
  • Openclaw 连接本地 Ollama 及 Qwen WebUI 无响应排查步骤
  • 使用 Java 调用飞书自定义机器人 Webhook
  • Dify 单独启动前端 Docker 容器
  • 基于 React 与 MediaPipe 的数字塔罗占卜系统设计与实现
  • OpenClaw 对接飞书实现多个机器人自动群聊配置
  • C++ 深入解析 std::back_inserter 用法与原理
  • Qwen2.5-7B 客服机器人云端对接微信指南
  • OpenClaw 安装百度网页搜索技能配置指南
  • 七大排序算法详解(下):冒泡、快速与归并排序
  • 深入理解 MCP 协议:与 Function Call 的区别及 Python 实战
  • C++ 的引用、inline 和 nullptr:怎么用才对
  • Vue 前端文件导出实战:file-saver 插件用法详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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