zoj2318

题意

一个平面上给出很多圆,其中一个圆为现在自己的位置,问这个圆能不能冲出其它圆的包围(不能与其它圆相交)。

分析

将所有圆心平移,使得自己的圆圆心处于原点,将所有圆半径增加自己圆的半径,这样自己的圆可以看成一个点,任意两圆相交我们都可以看作圆心间连了一条边,问题就转化成了一个点是否在一个多边形内,对于两点 \(A\) \(B\) ,我们可以把 \(A-B\) 这条有向边的权值置为角\(AOB\) 的角度,\(B-A\) 这条边的权值为角度取负,如果一个点在多边形内,那么跑一圈必然是 \(2*PI\) 或 \(-2*PI\) ,否则是 \(0\) ,跑一遍 \(Bellman-Ford\) 判断有无负环即可。

code

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e2 + 10;
const int MOD = 998244353;
const double EPS = 1e-9;
typedef long long ll;
int Sgn(double x) {
if(fabs(x) < EPS) return 0;
return x < 0 ? -1 : 1;
}
double Sqr(double x) {
return x * x;
}
struct Circle {
double x, y, r;
double dist(Circle c) {
return hypot(x - c.x, y - c.y);
}
bool Intersect(Circle c) {
return Sgn(c.r + r - dist(c)) > 0;
}
};
double Cross(Circle c1, Circle c2) {
return c1.x * c2.y - c2.x * c1.y;
}
double Dot(Circle c1, Circle c2) {
return c1.x * c2.x + c1.y * c2.y;
}
double Length(Circle c) {
return hypot(c.x, c.y);
}
double Angle(Circle c1, Circle c2) {
return acos(Dot(c1, c2) / Length(c1) / Length(c2));
}
Circle a[MAXN];
struct Edge {
int from, to;
double w;
Edge(int from = 0, int to = 0, double w = 0) : from(from), to(to), w(w) {}
}es[MAXN * MAXN];
double d[MAXN];
int n, cnt;
bool find_negative_loop() {
memset(d, 0, sizeof d);
for(int i = 0; i < n; i++) {
for(int j = 0; j < cnt; j++) {
Edge e = es[j];
if(Sgn(d[e.to] - d[e.from] - e.w) > 0) {
d[e.to] = d[e.from] + e.w;
if(i == n - 1) return true;
}
}
}
return false;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
cnt = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%lf%lf%lf", &a[i].x, &a[i].y, &a[i].r);
}
Circle O;
scanf("%lf%lf%lf", &O.x, &O.y, &O.r);
for(int i = 0; i < n; i++) {
a[i].x -= O.x;
a[i].y -= O.y;
a[i].r += O.r;
}
for(int i = 0; i < n; i++) {
for(int j = i + 1; j < n; j++) {
if(a[i].Intersect(a[j])) {
Circle c1 = a[i], c2 = a[j];
double sgn = 1;
if(Cross(c1, c2) < 0) sgn = -1;
double ang = Angle(c1, c2);
es[cnt++] = Edge(i, j, sgn * ang);
es[cnt++] = Edge(j, i, sgn * -ang);
}
}
}
puts(!find_negative_loop() ? "YES" : "NO");
if(T) puts("");
}
return 0;
}

zoj2318的更多相关文章

  1. OJ题目分类

    POJ题目分类 | POJ题目分类 | HDU题目分类 | ZOJ题目分类 | SOJ题目分类 | HOJ题目分类 | FOJ题目分类 | 模拟题: POJ1006 POJ1008 POJ1013 P ...

随机推荐

  1. gdb调试命令的使用及总结

    gdb调试命令的使用及总结 gdb是一个在UNIX环境下的命令行调试工具.如果需要使用gdb调试程序,请在gcc时加上-g选项.下面的命令部分是简化版,比如使用l代替list等等. 1.基本命令 命令 ...

  2. 【题解】[WC2006]水管局长

    感觉这题好强啊……本来以为能过,结果毫无疑问的被ge了一顿……在这里记录一下做的过程,也免得以后又忘记啦. 首先,我们应看出在这张图上,要让经过的水管最长的最短,就是要维护一棵动态的最小生成树.只是删 ...

  3. 【BZOJ 2503】相框 图论+讨论

    这道题目就是考验了一下图论基本知识与对可爱的代码实现的应对能力. 我们先分析题干信息.我们要形成相框,那么所有的点的度为2(参与的点),那么所有度大于2的点都需要熔断,而且一次完成所有关于这个点的熔断 ...

  4. CodeForces743E. Vladik and cards 二分+状压dp

    这个题我们可以想象成_---___-----__的一个水柱它具有一遍优一遍行的性质因此可以用来二分最小值len,而每次二分后我们都要验根,we可以把这个水柱想成我们在每个数段里取前一段的那个数后一段有 ...

  5. gogole调试请求体的数据怎么知道

    在network---->header->request payload中看 详细情况见下图所示:

  6. 使用vue开发webApp,安卓手机自带回退键的问题解决

    首先,我先为大家说明,为什么我要写这篇随笔: 因为我们写的webapp,在安卓手机上,按一次回退键,就会退出app,回到桌面,而不是像原生app一样,会有一个提示,例如,“再按一次退出应用”的这种提示 ...

  7. JQuery如何监听DIV内容变化

    这几天在做一个微博的接入,需要判断微博是否被关注,要检查微博标签的DIV是否有“已关注”的字符,但这个DIV的内容是微博JSSDK动态生 成.$("#id").html()是获取不 ...

  8. 基于MapReduce的手机流量统计分析

    1,代码 package mr; import java.io.IOException; import org.apache.commons.lang.StringUtils; import org. ...

  9. ILSPY反编译工具下载代替收费的Reflector工具

    原文发布时间为:2011-10-10 -- 来源于本人的百度文章 [由搬家工具导入] ILSPY反编译工具下载 http://build.sharpdevelop.net/BuildArtefacts ...

  10. Java环境变量配置以及作用、JDK与JRE区别以及命令行引入jar包

    在配置环境变量中: 设置JAVA_HOME: 一是为了方便引用,比如,JDK安装在C:\jdk1.6.0目录里,则设置JAVA_HOME为该目录路径, 那么以后要使用这个路径的时候, 只需输入%JAV ...