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;
}

最新文章

  1. 编写Java应用程序。首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能
  2. SQL日期格式转换
  3. (转) Graph-powered Machine Learning at Google
  4. Java编程思想学习(八) 内部类
  5. iOS通过设置info.plist参数使用iTunes导入导出Documents目录下的文件
  6. h5-4 canvas
  7. where, group by, having
  8. Linux系统常见的压缩命令
  9. 同步github工程gitcafe
  10. IntelliJ IDEA 17和Maven构建javaWeb项目
  11. flume1.8 开发指南学习感悟
  12. Hadoop3.0完全分布式集群安装部署
  13. CAD.NET二次开发 新建图层 删除图层 指定图层颜色以及线形等
  14. c#下载文件选择路径控件
  15. VSCode 必装的 10 个高效开发插件 --转
  16. JavaScript字符集
  17. WCF服务寄宿Windows
  18. Dynamic Shortest Path CodeForces - 843D (动态最短路)
  19. centOS6.6网络设置
  20. 解决Linux下IDEA无法使用ibus输入法的问题和tip乱码

热门文章

  1. LeetCode -- Merge Two Sorted Linked List
  2. IIS 发布后无法连接数据库(应用池问题)
  3. 【题解】NOI2009管道取珠
  4. Flink 任务打包、提交
  5. Linux总结(二)
  6. final变量属性小记
  7. 禁止 iphone 网页上下拖动露底
  8. (转)Django常用命令
  9. Linux下部署weblogic应用
  10. 转:A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程)