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

模拟算法实战:铺地毯、回文日期与扫雷解析

模拟算法核心在于枚举所有可能情况并筛选目标。结合铺地毯、回文日期与扫雷三例,演示如何从暴力枚举转向优化策略。铺地毯题利用逆序遍历快速定位;回文日期展示月日与年份的双向推导差异;扫雷则通过首列状态枚举推导全局。代码基于 C++ 编写,涵盖闰年判断、数组下标越界检查等细节,帮助读者理解模拟类问题的解题节奏与边界处理技巧。

极客工坊发布于 2026/3/16更新于 2026/7/2040 浏览
模拟算法实战:铺地毯、回文日期与扫雷解析

模拟算法实战

枚举是模拟算法的基础,核心思想是将所有可能的情况罗列出来,再筛选出符合题目要求的那一个。虽然暴力枚举容易超时,但在数据范围允许时,它是解决问题的直接手段。优化枚举策略(如顺序、对象选择)往往是解题关键。

一、铺地毯

1. 题目描述

给定 n 张地毯,每张地毯覆盖矩形区域。查询某个坐标 (x, y) 被哪一张地毯覆盖。如果有多个,输出最后铺设的那一张;如果没有,输出 -1。

铺地毯问题示意图

2. 思路分析

最直观的做法是遍历所有地毯判断是否覆盖。但题目要求的是最后一个覆盖该位置的地毯。如果正序枚举,必须遍历完所有地毯才能确定结果。更优的策略是逆序枚举:从最后一张地毯开始往前找,第一次遇到能覆盖 (x, y) 的地毯即为答案,找到即可返回,无需继续遍历。

3. 代码实现

#include <iostream>
using namespace std;

typedef long long LL;
const int N = 1e5 + 10;

LL a[N], b[N], g[N], k[N];
int n;

// 查找覆盖 (x, y) 的最后一张地毯编号
int find(int x, int y) {
    for (int i = n; i >= 1; i--) {
        // 判断当前地毯是否覆盖该点
        if (x >= a[i] && y >= b[i] && x <= a[i] + g[i] && y <= b[i] + k[i]) {
            return i;
        }
    }
    return -1;
}

int main() {
    cin >> n;
    for (int i = ; i <= n; i++) {
        cin >> a[i] >> b[i] >> g[i] >> k[i];
    }
    LL x, y;
    cin >> x >> y;
    cout << (x, y) << endl;
     ;
}
1
find
return
0

二、回文日期

1. 题目描述

给定两个日期 begin 和 end,统计其中有多少个日期是回文数(例如 20211202)。

回文日期示意图

2. 思路分析

回文日期的特点是年月日数字对称。这里提供两种枚举策略:

  1. 枚举月 + 日:固定月和日,根据回文特性反推年份。复杂度约为 O(10^3)。注意 2 月 29 日仅在闰年存在,需特殊处理或验证。
  2. 枚举年:固定年份,根据回文特性反推月和日。复杂度约为 O(10^4)。

策略一效率更高,因为月份和日的组合远少于年份的组合。在实现时需注意日期合法性校验(如闰年判断、每月天数限制)。

3. 代码实现

策略一:枚举月 + 日
#include <iostream>
using namespace std;

int m[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int main() {
    int begin, end;
    cin >> begin >> end;
    int ret = 0;
    // 枚举月份和日期
    for (int i = 1; i <= 12; i++) {
        for (int j = 1; j <= m[i]; j++) {
            // 构造回文年份部分
            int k = j % 10 * 1000 + j / 10 * 100 + i % 10 * 10 + i / 10;
            // 组合成完整日期数字 YYYYMMDD
            int num = k * 10000 + i * 100 + j;
            if (num >= begin && num <= end) {
                ret++;
            }
        }
    }
    cout << ret << endl;
    return 0;
}
策略二:枚举年
#include <iostream>
using namespace std;

// 判断是否为闰年
bool check_year(int y) {
    if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) return true;
    else return false;
}

// 数字反转函数
int reverse_num(int x) {
    int k = 0;
    while (x) {
        k = k * 10 + x % 10;
        x /= 10;
    }
    return k;
}

int main() {
    int begin, end;
    cin >> begin >> end;
    int x = begin / 10000;
    int y = end / 10000;
    int ret = 0;
    
    for (int i = x; i <= y; i++) {
        int k = reverse_num(i);
        int month = k / 100;
        int day = k % 100;
        int flag = 0;
        
        // 校验日期是否合法
        if (month > 0 && month <= 12) {
            if (check_year(i) && month == 2) flag = (day <= 29);
            else if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day <= 31) flag = 1;
            else if (month == 2) flag = (day <= 28);
            else if (month == 4 || month == 6 || month == 9 || month == 11) flag = (day <= 30);
            
            if (flag) {
                int palindrome_date = k + i * 10000;
                if (palindrome_date >= begin && palindrome_date <= end) {
                    ret++;
                }
            }
        }
    }
    cout << ret << endl;
    return 0;
}

三、扫雷

1. 题目描述

第一列给出每行格子周围地雷的总数,第二列给出地雷分布情况。已知第二列的部分信息,推断第一列是否有雷。

扫雷问题示意图

2. 思路分析

这是一个典型的逻辑推导问题。第一列的状态决定了后续行的状态。由于第一行第一列要么有雷(1),要么没雷(0),我们可以枚举这两种初始状态,然后依次推导后续行是否满足给定的地雷数量约束。

关键点在于边界检查:当计算到第 n 行时,需要确保第 n+1 行的地雷数为 0,否则说明推导出的状态不合法。此外,中间过程若出现负数或多于 1 的情况,也直接判定为非法。

3. 代码实现

#include <iostream>
using namespace std;

const int N = 1e4 + 10;
int a[N], b[N]; // a: 第一列地雷状态,b: 第二列地雷数量

// 假设第一格没有雷
int check1(int n) {
    a[1] = 0;
    for (int i = 2; i <= n + 1; i++) {
        // 根据相邻关系推导当前地雷数
        a[i] = b[i - 1] - a[i - 1] - a[i - 2];
        if (a[i] < 0 || a[i] > 1) return 0;
    }
    // 检查第 n+1 行是否闭合(应为 0)
    if (a[n + 1]) return 0;
    return 1;
}

// 假设第一格有雷
int check2(int n) {
    a[1] = 1;
    for (int i = 2; i <= n + 1; i++) {
        a[i] = b[i - 1] - a[i - 1] - a[i - 2];
        if (a[i] < 0 || a[i] > 1) return 0;
    }
    if (a[n + 1]) return 0;
    return 1;
}

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> b[i];
    
    int ret = 0;
    ret += check1(n);
    ret += check2(n);
    cout << ret << endl;
    return 0;
}

通过这三道题,我们可以看到模拟算法不仅仅是简单的循环,更需要结合数学规律进行剪枝和优化。在实际编码中,务必注意数组越界、闰年判断等细节,这些往往是调试时的'坑'。

目录

  1. 模拟算法实战
  2. 一、铺地毯
  3. 1. 题目描述
  4. 2. 思路分析
  5. 3. 代码实现
  6. 二、回文日期
  7. 1. 题目描述
  8. 2. 思路分析
  9. 3. 代码实现
  10. 策略一:枚举月 + 日
  11. 策略二:枚举年
  12. 三、扫雷
  13. 1. 题目描述
  14. 2. 思路分析
  15. 3. 代码实现
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • DeepSeek-r1 本地部署指南:使用 Ollama 与 Chatbox 快速搭建
  • AR 光学薄膜制备:高折射率与膜厚测量的椭偏仪应用
  • Linux 开源邮件服务及 iRedMail 部署实操指南
  • Python MCP 工具开发入门:Server、Client 与 LLM 集成
  • OpenTenBase 企业级分布式 HTAP 数据库部署全攻略
  • Webnovel Writer:基于 Claude Code 的长篇网文 AI 创作系统
  • Web Bluetooth API 实战:实现网页与 BLE 设备通信
  • AI Agent 架构:基础组成模块深度解析
  • Gaussian Grouping:在三维场景中分割与编辑任意对象
  • 构建企业级私有化 AI:从大模型原理到本地智聊机器人全栈部署指南
  • Tomcat 8.5 安装与环境配置
  • Z-Image Turbo 画板:低显存 AI 绘画稳定生成指南
  • 基于大语言模型的智能爬虫 Crawlab AI 实践
  • VS Code 远程连接服务器后 GitHub Copilot 无法使用的修复方法
  • 含风光发电电力系统概率潮流计算:蒙特卡洛与半不变量法
  • Web Scraper 快速上手:网页数据批量采集指南
  • Claude 注册中的手机号验证怎么处理
  • Python 爬虫 403 错误处理:Selenium 与普通请求对比
  • SkyWalking Java Agent 配置实战:IDEA 与 Tomcat 多场景详解
  • 2024 年十大高效 AI 办公与学习工具推荐

相关免费在线工具

  • 加密/解密文本

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