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. [洛谷P3382]【模板】三分法

    题目大意:给出一个$N$次函数,保证在范围$[l,r]$内存在一点x,使得$[l,x]$上单调增,$[x,r]$上单调减.试求出$x$的值. 题解:求导,就变成了求零点,二分答案即可 卡点:无 C++ ...

  2. BZOJ 2226 [Spoj 5971] LCMSum | 数论拆式子

    题目: http://www.lydsy.com/JudgeOnline/problem.php?id=2226 题解: 题目要求的是Σn*i/gcd(i,n) i∈[1,n] 把n提出来变成Σi/g ...

  3. timeSetEvent()函数

    原文链接地址:http://www.cnblogs.com/kangwang1988/archive/2010/09/16/1827872.html 微软公司在其多媒体Windows中提供了精确定时器 ...

  4. [Leetcode] first missing positve 缺失的第一个正数

    Given an unsorted integer array, find the first missing positive integer. For example,Given[1,2,0]re ...

  5. 深入研究JavaScript的事件机制

    本篇开始将回顾下Javascript的事件机制.同时会从一个最小的函数开始写到最后一个具有完整功能的,强大的事件模块.为叙述方便将响应函数/回调函数/事件Listener/事件handler都称为事件 ...

  6. eclipse中的debug按钮组突然找不到了,找回方法

  7. (转)用python实现抓取网页、模拟登陆

    涉及一系列内容,部分已在前面转载,仍转自crifan: http://www.crifan.com/how_to_use_some_language_python_csharp_to_implemen ...

  8. 汕头市队赛 yyl杯1 T1

    A SRM 05 - YYL 杯 R1 背景 傻逼题 描述 给一个序列,序列里只有两种元素1和2.现在要从序列里选出一些非空子序列使得子序列里两种元素数量相同.问有多少种方案数? 输入格式 多组数据 ...

  9. bzoj 1076 状压DP

    我们设w[i][s]为当前到第i关,手中的物品为s的时候,期望得分为多少,其中s为二进制表示每种物品是否存在. 那么就比较容易转移了w[i][s]=(w[i-1][s']+v[j]) *(1/k),其 ...

  10. certbot 免费httos证书申请

    https://keelii.com/2016/06/12/free-https-cert-lets-encrypt-apply-install/