洛谷P2864
来一发在洛谷的第一篇题解
解析
首先从原点出发回到原点会形成一个环
要计算在环上的路程,首先我们要破环
利用建墙法破环
可以选取任意一个边缘上的树,往上或者往下或者往左往右建立一堵墙‘|’
这样利用bfs搜索的时候无法穿过这堵墙
如下所示我们在第一棵树上面建了一堵墙,隔绝了左右两个部分
...|...
...|...
...X...
..XXX..
...XXX.
...X...
......*
从起点到相邻着墙左边的点的最短距离+到相邻着墙右边点的最短距离+在墙上走的距离之和(因为实际上我们还是要走墙这一段距离),求其最小值就是我们需要的答案
解法正确性证明
假设我们已经通过这种方法求出来一个解,存在比这种解法更优的解法
首先我们知道这种更优的解法也一定会穿过墙,并且对应墙相邻左右的两个点
我们的这种解法其中一种情况也同样对应墙两边相邻左右的两个点,并且与更优解的这两个点对应
(原解法)
设x1是起点到墙左边这个点的距离,x2是到右边点的距离,x3是中间在墙上经过的距离
(更优解)
x11与x22,x33和上面x1,x2,x3定义一样,
那么一定有x1 + x2 < x11 + x22
如果更优解存在,那么x3 > x33
说明在墙上的距离存在比x3更小
然而我们所想的方法求得是x1 + x2 + x3 的最小值
如果x33 比x3更小,那么显然x1+x2+x33才是我们所想方法的解
这和假设相矛盾
即可得证
代码
#include<iostream>
#include<utility>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
#define fi(i,a,b) for(int i = a; i <= b; ++i)
#define fr(i,a,b) for(int i = a; i >= b; --i)
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define pb push_back
using pii = pair<int,int>;
//#define DEBUG
int dis[55][55];//最短路数组
char forest[55][55];//样例数据
bool vis[55][55];//标记是否访问过
int qx,qy;//第一棵树
int sx,sy;//起始点
int n,m;
int res = 0x3f3f3f3f;//答案
int dx[8] = {1,1,1,0,0,-1,-1,-1};
int dy[8] = {1,0,-1,1,-1,1,0,-1};//方向数组
struct point{
int x,y,k;
};//分别表示坐标和最短路
void bfs(int x,int y){
queue<point> que;
que.push({sx,sy,0});
vis[sx][sy] = true;
while(!que.empty()){
point temp = que.front();
que.pop();
fi(i,0,7){
int p = temp.x + dx[i];
int q = temp.y + dy[i];
if(p >= 1 && p <= n && q >= 1 && q <= m && forest[p][q] == '.' && !vis[p][q]){
vis[p][q] = true;
dis[p][q] = temp.k + 1;//bfs第一个访问到得就是最短路
que.push({p,q,dis[p][q]});
}
}
}
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int bk = 0;
fi(i,1,n) fi(j,1,m) {
cin >> forest[i][j];
if(forest[i][j] == 'X' && !bk){
qx = i,qy = j;
bk = 1;
}//标记第一颗树
else if(forest[i][j] == '*'){
sx = i,sy = j;
}
}
fi(i,1,qx-1){
forest[i][qy] = '|';
} //把第一棵树上面得所有点变成墙
bfs(sx,sy);
fi(i,1,qx) fi(j,1,qx){//循环到qx因为可以斜着走
if(forest[i][qy-1] == '.' && forest[j][qy+1] == '.')//循环墙得左右两边得点
res = min(dis[i][qy-1] + dis[j][qy+1] + abs(i-j) + 1,res);
}
cout << res +1 << endl;//加上原点
#ifdef DEBUG
//freopen(D:\in.txt,r,stdin);
#endif
return 0;
}
洛谷P2864的更多相关文章
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
- 洛谷P1538迎春舞会之数字舞蹈
题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...
- 洛谷八月月赛Round1凄惨记
个人背景: 上午9:30放学,然后因为学校举办读书工程跟同学去书城选书,中午回来开始打比赛,下午又回老家,中间抽出一点时间调代码,回家已经8:50了 也许是7月月赛时“连蒙带骗”AK的太幸运然而因同学 ...
- 洛谷 P1379 八数码难题 Label:判重&&bfs
特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给 ...
- [洛谷OJ] P1114 “非常男女”计划
洛谷1114 “非常男女”计划 本题地址:http://www.luogu.org/problem/show?pid=1114 题目描述 近来,初一年的XXX小朋友致力于研究班上同学的配对问题(别想太 ...
随机推荐
- DashVector + DashScope升级多模态检索
本教程在前述教程(DashVector + ModelScope玩转多模态检索)的基础之上,基于DashScope上新推出的ONE-PEACE通用多模态表征模型结合向量检索服务DashVector来对 ...
- windows下使用winget快速安装nvm
前置条件: 操作系统 >= win10 安装 首先使用winget搜索nvm包 winget search nvm #搜索结果如下图 安装nvm winget install CoreyButl ...
- linux下date命令设置时间的输出格式和修改时间
目录 一.关于linux下的时间 二.linux下使用date命令设置时间的输出格式 三.修改linux时间 3.1 在可以访问Internet情况下修改时间 3.2 在无法访问Internet情况下 ...
- fabric compose文件解读(Orderer篇)
orderer在fabric中的作用是排序,另外orderer有点像是管理节点一样,通道之类的都是在orderer的基础之上建立的,有点像比特币,以太坊上面的全节点一样,不过责任比全节点少很多,甚至都 ...
- 利用QEMU模拟大端序机器
简介 当前我们安装虚拟机,一般小端机器比较多,有时候想模拟大端机器测试程序,这时就有模拟大端机器的需求. 参考:利用 QEMU USER 模式运行 mips 程序 - sinpo828 - 博客园 ( ...
- 基于Vue的二进制时钟组件 -- fx67llBinaryClock
fx67llClock Easy & Good Clock ! npm 组件说明 一个基于Vue的二进制时钟组件,没什么卵用,做着好玩,可以方便您装饰个人主页 使用步骤 npm install ...
- 此计算机上不存在虚拟机管理服务(VMMS)。请确保已启用“Hyper-V 服务”功能。
此计算机上不存在虚拟机管理服务(VMMS).请确保已启用"Hyper-V 服务"功能. 解决方法: 在主板BIOS 里开启VT. Intel Virtualization Tech ...
- 蓝屏rtux64w10.sys
蓝屏rtux64w10.sys 环境: WIN10 + Realtek USB RTL8156B 2.5G网卡 表现: 局域网复制时,间隔性速度变为0,多次后,最终蓝屏. 解决方法: 更新驱动. 地 ...
- vmware 虚拟WIN10 chrome核心浏览器部分菜单花掉
解决方法:在vmware 显示器设置中,关闭"加速 3D 图形".
- Semantic Kernel入门系列:通过依赖注入管理对象和插件
前言 本章讲一下在Semantic Kernel中使用DependencyInject(依赖注入),在之前的章节我们都是通过手动创建Kernel对象来完成框架的初始化工作,今天我们用依赖注入的方式来实 ...