当前位置: 首页 > news >正文

题解:P14065 [PO Final 2022] 对弈 / Laserschack

题目传送门

先警示后人:
我在看题目的时候看成了 \(1 \le r,c \le 4000\)
然后被迫想了一个 \(\operatorname{O}(\operatorname{RC} \ \operatorname{log} \ \operatorname{RC})\) 发现好像有点玄
最后乱加一堆优化跑爆了只能重写


正解:

  • 对于这个数组考虑 二维 转 一维 ,静态数组存不下
    如果喜欢用动态二维数组自然是很好的()
  • 算法上考虑两遍 BFS 直接秒了,下面开始介绍思路

第一遍 BFS:

我们多源 BFS 对所有 R 进行扩展
更新图上每个点最早被烟雾覆盖的时间 \(\operatorname{time[\ ]}\)
BFS 的特性可以保证这样遍历到的每个点确实是正确的
\(\operatorname{O(RC)}\)

第二遍 BFS:

从 A 开始或从 K 开始都无所谓,我喜欢反图就从 K 开始了

  • 我们的目标:
    找到所有合法路径(即能从 A 到达 K 的路径)最晚被烟雾碰到的那条路,并且求出这条路上最小的 \(\operatorname{time[\ ]}\)

  • 实现方式:
    从 K 开始遍历四个方向

    如果找到了边界,就 break
    如果找到了 o ,说明找到一条子路了,就判断当前子路存的 path_time[ ] 是否小于当前手里搜出来的最小断点,如果是,就拿手里这个更新这个子路的 path_time[ ]
    如果找到了 A ,说明走通了一条合法路径,我们拿手里的最小断点直接去 \(\max(\operatorname{ans,current})\)

    而这个 BFS 的队列的存储要使用大根堆的优先队列来尽可能的贪心,就像 dijkstra 选取最小边来扩展
    我们从队列里面拿出任意一个点的时候,将他的最早断点与此时的 ans 对比,如果这个最早断点早于 ans ,那么直接可以 continue
    这时 \(\operatorname{O(RC \ log \ RC)}\)

  • 正确性简证:
    激光不经过任何烟雾,从而攻击到国王。
    也就是所有 A 到 K 的合法路径上都存在烟雾,求这个最早的时间
    转换成不以时间为变量,求所有路径上最早断点最晚的路径,当这个路径被遮住是,其他所有路径也早就被遮住

细节都在代码里了
注释清晰,码风优良


\(\mathbb {\LARGE C \large _O \ \Large ^D \normalsize _E}\)

#include<bits/stdc++.h>using namespace std;const int N = 4002;
const int dx[5] = {0, 1, -1, 0, 0};
const int dy[5] = {0, 0, 0, 1, -1};struct SMOKE {int x, y;
};queue< SMOKE >R;//存储R的坐标,用于多源BFS预处理图 int r, c, in_x, in_y, pth_min;//in_x,in_y存国王的坐标 
int a[N << 4], SMoke_TIme[N << 4], vis[N << 4]; //a存图; SMoke_TIme存烟雾的时间层; vis存当前点(只有镜子才会有)的最早断点 
int ans = 0;
int x , y, xx, yy, v;void input(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> r>> c;for(int i = 1; i <= r; i++){for(int j = 1; j <= c; j++){SMoke_TIme[c * (i - 1) + j] = -1;char ch;cin >> ch;if(ch == 'o') a[c * (i - 1) + j] = 4;if(ch == '.') a[c * (i - 1) + j] = 0;if(ch == 'A') a[c * (i - 1) + j] = 1;if(ch == 'K') {a[c * (i - 1) + j] = 2;in_x = i;in_y = j;//存储国王位置 }if(ch == 'R') {a[c * (i - 1) + j] = 3;R.push(SMOKE{i, j});//烟雾初始位置入队保存 SMoke_TIme[c * (i - 1) + j] = 0;}}}
}void output(){cout << ans << endl;
}void BFS(){//多源BFS预处理图的时间层 while( !R.empty()){x = R.front().x;y = R.front().y;R.pop();for(int i = 1; i <= 4; i++){//四个方向扩散 xx = x + dx[i];yy = y + dy[i];if(xx < 1 or yy < 1 or xx > r or yy > c or SMoke_TIme[c * (xx - 1) + yy] != -1)continue;//边界条件//BFS能保证每个点搜到的时候都是距离他最近的烟雾为祖先//也就是能保证SMoke_TIme最小 SMoke_TIme[c * (xx - 1) + yy] = SMoke_TIme[c * (x - 1) + y] + 1;//是自己祖先的下一秒 R.push(SMOKE{xx, yy});}}
}struct path{int x, y;int v;//到这个镜子的这条路径上的最早阻断点,也就是这条路最早失效的时间 bool operator <(const path &other)const {return v >= other.v;//优先队列取出当前最优解(就是最晚被干掉的合法路径) }
};priority_queue< path >q;void solve_BFS(){//从国王位置倒着搜所有合法路径 for(int i = 1; i <= 4; i++){xx = in_x;yy = in_y;pth_min = SMoke_TIme[c * (xx - 1) + yy];while(true){xx += dx[i];yy += dy[i];if(xx < 1 or yy < 1 or xx > r or yy > c)break;//边界条件判断 if(a[c * (xx - 1) + yy] == 3) break;//剪枝 pth_min = min(pth_min, SMoke_TIme[c * (xx - 1) + yy]);if(a[c * (xx - 1) + yy] == 4){//遇到镜子就停止这个方向的初始化vis[c * (xx - 1) + yy] = max(vis[c * (xx - 1) + yy], pth_min);q.push(path{xx, yy, pth_min}); break;}if(a[c * (xx - 1) + yy] == 1){//遇到A就说明可以直接返回这条路线了 ans = max(ans, pth_min);break;}}}while(!q.empty()){path t = q.top();q.pop();if(t.v <= ans)continue;//剪枝优化:当前这条路径已经废了,被阻挡的时间比我们已经求出来的还早 for(int i = 1; i <= 4; i++){xx = t.x;yy = t.y;pth_min = t.v;while(true){xx += dx[i];yy += dy[i];if(xx < 1 or yy < 1 or xx > r or yy > c) break;//边界条件判断if(a[c * (xx - 1) + yy] == 3)break;//剪枝 pth_min = min(pth_min, SMoke_TIme[c * (xx - 1) + yy]);//更新路径 if(a[c * (xx - 1) + yy] == 4){if(pth_min > vis[c * (xx - 1) + yy]){//如果是更好的子路 vis[c * (xx - 1) + yy] = pth_min;q.push(path{xx, yy, pth_min});}break;}if(a[c * (xx - 1) + yy] == 1){//合法路径直接返回 ans = max(pth_min, ans);break;}}}}
}main(void){input();BFS();solve_BFS();output();
}
http://www.gsyq.cn/news/18388.html

相关文章:

  • CF2064E Mycraft Sand Sort
  • 20251010周五日记
  • HTML5拖放API核心功能解析
  • Umi-OCR_文字识别工具 免安装使用教程(附下载安装包)!永久免费,开源离线OCR识别软件下载
  • 表格识别:不仅能识别文字,更能理解表格的结构和逻辑关系,实现输出可编辑、可分析的结构化数据
  • docker容器的三大核心技术UnionFS(下) - 指南
  • P13274 [NOI2025] 三目运算符
  • B2002 Hello,World!【入门】
  • 华为链路聚合配置
  • iOS 26 软件性能测试全流程,启动渲染资源压力对比与优化策略 - 详解
  • 手机adb 调试自己
  • 2025 年公共/商场/学校/地铁/电影院/会所/机场/卫生间隔断厂家选购指南:优质厂商推荐与实用选择策略
  • Java环境安装备忘录
  • 详细介绍:标准型ELN成主流:定制型为何“遇冷”?
  • 【Linux】Ext系列文件系统(下) - 实践
  • 2025 年水产养殖降氨氮亚盐厂家最新推荐排行榜 ,助力北方对虾鱼塘螃蟹池塘养殖户轻松选购优质产品
  • 2025 年玻璃钢水箱生产厂家最新推荐榜单:含 30 吨 / 订做 / 消防 / 方形 / 拼装式 / 屋顶 / 大型产品,从产能与服务双维度精选优质企业
  • crontab 定时执行python脚本失败,但手动执行却成功问题处理 - hello-*
  • 2025 年不锈钢水箱厂家最新推荐榜:优质厂家实力对比与选购指南,助您选到适配设备矩形/屋顶/定做方形不锈钢水箱厂家推荐
  • 实用指南:Java 后端面试技术文档(参考)
  • 2025 年钢结构厂家最新推荐榜:优质企业全面解析,助力客户精准选择可靠合作伙伴
  • 2025规划馆运营厂家 TOP 榜:苏州金梓树智能科技,专注场馆全周期服务,规划馆运维优质服务商推荐!
  • 2025 高温线缆厂家 TOP 榜:奇温线缆 (上海) 有限公司,专注特种高温领域,定制化高温线缆源头厂家推荐!
  • OI 笑传 #17
  • 实用指南:Python Tkinter构建交互式精灵表切割桌面应用程序:将精灵表分割成单个帧的功能
  • 题解:qoj7979 棋盘
  • 2025 年最新推荐微波干燥设备生产厂家排行榜,覆盖多行业高效干燥解决方案权威推荐黄粉虫/黑水虻/中药材/茶叶微波干燥设备厂家推荐
  • 控制台
  • 2025 年最新三维扫描仪厂家权威排行榜:聚焦高精度与多场景适配,为企业与个人用户精选优质品牌推荐高精度/专业/手持激光/工业/便携式三维扫描仪厂家推荐
  • 2025 年最新推荐!国内优质充电桩厂家排行榜,涵盖多场景适配产品,助用户精准选靠谱品牌智能/新能源/电动车/重卡/电动车直流充电桩厂家推荐