Artwork (Gym - 102346A)【DFS、连通块】
Artwork (Gym - 102346A)
算法
DFS,连通块
时间复杂度:O(k*n + k * k)
1.这道题就是让你判断从(0,0)到(m,n),避开中途所有的传感器(传感器的检测范围为半径为s的圆)的检测区域,最终能否到达(m,n)。
2.这道题很容易想到圆与圆相切或相交最后把能出去的路全堵上了,具体是把上下、左右、左下、右上这四个边界给堵掉一部分(只要满足前面四种情况的其中一个,就过不去)。见下图。
很明显,这样堵绝对出不去。然而方法是有,但怎么实现它呢?由于当时以为这是个复杂的计算几何的题,结果看了半天计算几何模板却无从下手(其实只涉及了一点计算几何的知识,就是判断两个圆是否相交或相切),最终未果。查阅了一些解题博客后了解到该题可以用DFS,连通块的思想来实现,当然还有是用并查集实现,不过并没有看并查集是怎么实现它的,这里先只介绍如何用DFS来实现它。
3.首先应明确一点,就是如何判断两圆是否相交或相切,即圆心之间的距离要大于等于半径之和。
d = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2))
d >= r1 + r2
为了避免sqrt后影响精度,故两边都开平方
d*d >= (r1 + r2)*(r1 + r2)
即(x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) >= (r1 + r2)*(r1 + r2)
4.如果两个圆相交或相切,我们可以就把它们视为一体,这样就构成了一个连通块,判断连通块是否满足上面四个条件。至于如何判断,就是判断连通块中的每个圆是否触及边界,具体用下列式子来判断。
x - r <= 0 --> 触及左边界
x + r >= m --> 触及右边界
y - r <= 0 --> 触及下边界
y + r >= n --> 触及上边界
5.好了,现在知道怎么判断是否触及边界了,那么就需要想一下怎么知道连通块中包含哪些圆呢?这里我们可以借助图论的相关知识。就是如果两个圆有接触,就在这两个圆之间建立一条连接,我们可以把这个圆抽象成一个节点,这就变成了在两个节点之间建立一条无向边,这个连通块就成了一个图。遍历这个图即可知道这个连通块包含哪些圆。
6.大致的实现思路有了,现在我们来看如何用代码实现。
C++代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1010, M = 2e6 + 10; //注意M要取到N*N,原因是其中一个圆可能和其他所有圆都相交或相切
int m, n, k;
struct Sensor{
int x, y, s;
}sen[N];
int h[N], e[M], ne[M], idx;
bool st[5]; //0,1,2,3分别代表上下左右四个边界是否接触
bool vis[N]; //该圆是否被访问过
void add(int a, int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
//判断两圆是否相交或相切
bool check(Sensor a, Sensor b)
{
if((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) <= (a.s + b.s) * (a.s + b.s)) return true;
return false;
}
void dfs(int u)
{
vis[u] = true;
int x = sen[u].x, y = sen[u].y, s = sen[u].s;
if(x - s <= 0) st[2] = true;
if(x + s >= m) st[3] = true;
if(y - s <= 0) st[1] = true;
if(y + s >= n) st[0] = true;
//遍历与该圆连通的圆
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if(!vis[j])
dfs(j);
}
}
int main()
{
cin >> m >> n >> k;
memset(h, -1, sizeof h);
for(int i = 0; i < k; i++)
cin >> sen[i].x >> sen[i].y >> sen[i].s;
for(int i = 0; i < k; i++)
for(int j = i + 1;j < k; j++)
{
if(check(sen[i], sen[j]))
{
add(i, j);
add(j, i);
}
}
bool flag = false;
for(int i = 0; i < k; i++)
{
if(flag) break;
if(vis[i]) continue;
memset(st, 0, sizeof st);
dfs(i);
if((st[0] || st[2]) && (st[1] || st[3]))
flag = true;
}
if(flag)
puts("N");
else
puts("S");
}
此代码中使用的用邻接表建立图来源于yxc大佬的模板
解题思路来源
Artwork (Gym - 102346A)【DFS、连通块】的更多相关文章
- DFS(连通块) ZOJ 2743 Bubble Shooter
题目传送门 题意:从炮台射出一个球,三个及以上颜色相同的会掉落,问最后会掉落多少个球 分析:先从炮台找一个连通块,然后与顶部连接的连通块都不会掉落,剩下的就是炮台射出后跟随掉落的. #include ...
- Codeforces Round #375 (Div. 2)——D. Lakes in Berland(DFS连通块)
D. Lakes in Berland time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- P1141 01迷宫 dfs连通块
题目描述 有一个仅由数字000与111组成的n×nn \times nn×n格迷宫.若你位于一格0上,那么你可以移动到相邻444格中的某一格111上,同样若你位于一格1上,那么你可以移动到相邻444格 ...
- ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Time Limit: 2 Seconds Me ...
- ZOJ 3781 Paint the Grid Reloaded(DFS连通块缩点+BFS求最短路)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5268 题目大意:字符一样并且相邻的即为连通.每次可翻转一个连通块X( ...
- DFS(连通块) HDU 1241 Oil Deposits
题目传送门 /* DFS:油田问题,一道经典的DFS求连通块.当初的难题,现在看上去不过如此啊 */ /************************************************ ...
- C - CodeCoder vs TopForces Gym - 101142C (连通块+思维)
题目链接: C - CodeCoder vs TopForces Gym - 101142C 题目大意:给你n个人的信息,每一个人的信息包括两个.t1和t2.A>B的前提是A的t1和t2至少有一 ...
- HDU1241 Oil Deposits(dfs+连通块问题)
背景描述 ztw同志负责探测地下石油储藏.ztw现在在一块矩形区域探测石油.他通过专业设备,来分析每个小块中是否蕴藏石油.如果这些蕴藏石油的小方格相邻(横向相邻,纵向相邻,还有对角相邻),那么它们被认 ...
- Gym 102346A Artwork dfs
Artwork Gym - 102346A 题意:给n*m的地图,入口是(0,0),出口是(n,m),其中有k个监视器,坐标是(xi,yi),监视半径是r,问一个人能不能不被监视到,从起点到终点. 如 ...
随机推荐
- ms-data(转载)
转载:https://www.cnblogs.com/zll-52011/p/10960905.html 1.从美国矿物数据库下载矿物CIF(有晶格) 2.晶胞CIF导入MS 3.选择display ...
- PowerJob 在线日志饱受好评的秘诀:小但实用的分布式日志系统
本文适合有 Java 基础知识的人群 作者:HelloGitHub-Salieri HelloGitHub 推出的<讲解开源项目>系列. 项目地址: https://github.com/ ...
- iNeuOS工业互联平台,WEB组态(iNeuView)集成实时预警和报警柱状图
目 录 1. 概述... 2 2. 平台演示... 2 3. 应用过程... 2 4. 实时数据展示效果... 3 1. 概述 对于我们 ...
- 从String类型发散想到的一些东西
值类型 引用类型 值类型表示存储在栈上的类型,包括简单类型(int.long.double.short).枚举.struct定义: 引用类型表示存在堆上的类型,包括数组.接口.委托.class定义: ...
- Min Cost Climbing Stairs [746]
Min Cost Climbing Stairs [746] 题目描述 简单来说就是:要跳过当前楼梯需要花费当前楼梯所代表的价值cost[i], 花费cost[i]之后,可以选择跳一阶或者两阶楼梯,以 ...
- Struts+Servlet+JDBC网上手机销售系统
项目描述 Hi,大家好,今天给大家分享一个<网上手机销售系统>.本系统一共分为前台和后台两大模块,两个模块之间虽然在表面上是相互独立的,但是在对数据库的访问上是紧密相连的,各个模块访问的是 ...
- e3mall商城的归纳总结8之solr集群、activemq的搭建和使用
由于本节内容比较分散,因此专门为这两个技术进行开展了帖子. solr集群的搭建 solr集群solrJ的测试 activemq的搭建 activemq的使用 引入activemq.jar包 我们先来说 ...
- 数字电路基础(三)TTL与非门输入端接电压表的示数
如下图所示,当ui输入低电平,电压表示数为0.3v,当ui输入高电平时,电压表示数为1.4v,分析如下 当ui=0.3 此时VT1导通,电流都从输入端流出,VT1的基极电位被钳位在1.0v(Ub1=0 ...
- 如何配置node环境变量
1,安装node.js 最后安装的目录在 检测node安装成功 node -v 如果报错 没有默认装在c盘 pro 需要配置环境变量 Npm node package manag ...
- Spring源码学习(六)-spring初始化回调方法源码学习
1.spring官方指定了三种初始化回调方法 1.1.@PostConstruct.@PreDestory 1.2.实现 InitializingBean DisposableBean 接口 1.3. ...