news 2026/6/30 2:42:50

ATCODER ABC 450 C

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ATCODER ABC 450 C

因为想不到或者不知道这道题的算法是什么,我想枚举模拟,但是在枚举模拟的过程中,我发现,我模拟从一个串的开始到串的末尾,这个过程很难模拟出来,所以暴力做法也写不出来,最后,看官方题解以及问ai,才知道这道题要用BFS(广度优先搜索)

BFS:

为什么要用BFS

  1. 这道题是一个连通块问题,等效于要求我们统计“不漏水”的水坑,bfs的核心思想就是从一个点开始,向四周扩散,所以这道题的要求很契合bfs

具体思路

  • 用两个数组表示平移到上下左右

  • 用一个二维bool数组表示该格子是否被扫描过

  • 循环每个字符

    • 假如一个字符没被扫描过,并且是.,以它为头建造一个队列(存储pair),记住存入队列就马上标记(原因见下文).

    • 设定一个bool数来表示连通串是否有点在边界

    • bfs寻找:首先判断当前的坐标是否在边界内,即使在边界,还是要把邻居找完,不然之后还是循环到邻居还是要再找,可能导致重复找邻居,效率低下.找邻居(注意判断坐标边界条件,将邻居push进队列,进队列就标记)

    • 进队列就标记的原因:

      如下例子所示:

      1. 2×2 地图的“包抄”过程

      假设四个点全是水坑.

      • A—— 起点
      • B—— A 的下方邻居
      • C—— A 的右方邻居
      • D——B 的右方邻居,同时也是 C 的下方邻居
      1. 第一步:处理 A
        • A 看向四周,发现了 B 和 C 。
        • A 把 B 和 C 都丢进队列排队。
        • 此时队列[B, C]注意:此时 B 和 C 还没出队,所以还没被贴上cg=1的标签。
      2. 第二步:轮到 B 出队
        • B 贴上标签cg[1][0]=1
        • B 看向它的邻居,发现了D
        • B 发现 D 还没贴标签,于是把D 丢进队列
        • 此时队列[C, D]注意:此时 D 已经在排队了,但因为还没出队,它的标签cg[1][1]依然是 0。
      3. 第三步:轮到 C 出队
        • C 贴上标签cg[0][1]=1
        • C 看向它的邻居,也发现了D
        • 关键冲突点:C 检查cg[1][1],发现竟然是0(因为 D 还在后面排队呢,没轮到它贴标签)。
        • C 以为 D 是个没人管的“新发现”,于是又把 D 丢进了一次队列
        • 最终队列[D, D]

      2. 为什么这很可怕?

      虽然 和 互不相识,但它们像两个不沟通的部门,同时看中了同一个员工D

      • 在一个大迷宫里,任何一个空格子(比如 )通常都有 4 个邻居。
      • 这意味着,如果你不在入队那一刻就贴上标签,这个格子可能会被它的上下左右邻居每人举报一次
      • 在你的while循环里,原本这个格子只需要处理 1 次,现在却要处理 4 次。而这 4 次处理又会引发出更多的重复……这种冗余会像病毒一样在你的队列里疯狂繁殖。
    • 假如队列空后bool数不变,那么++count

代码:

#include <bits/stdc++.h> using i64 = long long; int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, 1, -1}; void solve(){ int h, w; std::cin >> h >> w; std::vector<std::string> s(h); for(int i = 0; i < h; ++i){ std::cin >> s[i]; } std::vector<std::vector<bool>> cg(h,std::vector<bool> (w,0)); int count = 0; for(int i = 0; i < h; ++i){ for(int j = 0; j < w; ++j){ if(s[i][j] == '.' && cg[i][j] == 0){ std::queue<std::pair<int, int>> q; q.push({i,j}); cg[i][j] = 1; bool is = 1; while(!q.empty()){ auto[x,y] = q.front(); q.pop(); int nx, ny; if(x == 0 || x == h - 1 || y == 0 || y == w - 1){ is = 0; } for(int k = 0 ; k < 4; ++k){ nx = x + dx[k]; ny = y + dy[k]; if(nx >= 0 && nx < h && ny >= 0 && ny < w){ if(s[nx][ny] == '.' && cg[nx][ny] == 0){ q.push({nx,ny}); cg[nx][ny] = 1; } } } } if(is == 1){ ++count; } } } } std::cout << count; } int main(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); solve(); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/30 2:40:05

财报分析AI工具各产品信息处理适配场景梳理

财报分析AI工具各产品信息处理适配场景梳理 一、普通投资者整理财报与研究记录时普遍存在的信息管理痛点 大多数自主整理财报、研读研报、日常复盘记录的个人使用者&#xff0c;都会长期面临信息碎片化带来的效率损耗。行业资讯、上市公司财报PDF、券商深度研报、每日行情观察…

作者头像 李华
网站建设 2026/6/30 2:38:17

Windows系统文件AddressParser.dll丢失找不到问题解决

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/6/30 2:36:46

Day5:用户端用例执行与缺陷管理

日期&#xff1a;2026-6-29&#x1f6e0; 一、 做了什么全面执行用户端功能与专项测试用例&#xff1a;对之前设计好的 160 条 用户端核心用例进行了逐一的实操执行。完成了用例状态的全面梳理&#xff1a;在本地的禅道开源版环境里&#xff0c;完成了对所有用例的实际结果判定…

作者头像 李华
网站建设 2026/6/30 2:36:24

SpiderFoot开源情报工具:从部署到实战的自动化信息收集指南

1. 先搞清楚 SpiderFoot 到底能帮你做什么如果你在负责安全运维、渗透测试或者威胁情报收集&#xff0c;经常需要手动去查一个域名、IP地址或者邮箱背后的关联信息&#xff0c;比如它绑定了哪些子域名、关联了哪些历史IP、有没有在公开漏洞库出现过&#xff0c;那 SpiderFoot 这…

作者头像 李华
网站建设 2026/6/30 2:35:48

01Linux概述

本章目标 了解Linux的发展史以及常见Linux发行版【了解】会在VMWare虚拟机下安装常见Linux【掌握&#xff0c;重点】理解VMware虚拟机的三种网络模式【理解、重点、难点】掌握如何在VMware的快照和克隆功能【掌握】 本章内容 一、Linux简介 常见的操作系统 windows:个人办…

作者头像 李华