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. 【心情】HNOI2018游记

    Day 0. 全机房的人好像都在做题.然而下午是社团节的游园会,身为社干的我风风雨雨在外面各种搬凳子搬椅子换场地招待外校同学……就这样我好像什么都没有复习. 晚上就一起去酒店了.大概因为是高一的缘故, ...

  2. [bzoj2621] [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper

    题目链接 状压\(dp\) 根据套路,先设\(f[sta]\)为状态为\(sta\)时所用的最小分组数. 可以发现,这个状态不好转移,无法判断是否可以装下新的一个物品.于是再设一个状态\(g[sta] ...

  3. [CF1076E]Vasya and a Tree

    题目大意:给定一棵以$1$为根的树,$m$次操作,第$i$次为对以$v_i$为根的深度小于等于$d_i$的子树的所有节点权值加$x_i$.最后输出每个节点的值 题解:可以把操作离线,每次开始遍历到一个 ...

  4. Contest Hunter 模拟赛09 A [线段树维护斜率]

    题面 传送门 思路 首先看看我们到底要干什么:有$1e6$次询问,遍历$i$,每次要求一个形如$b_i \ast a_j - a_i \ast b_j$的东西的最大值 考虑如果一个$j$的决策在当前的 ...

  5. [Leetcode] candy 糖果

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  6. IOI1998 Polygon [区间dp]

    [IOI1998]Polygon 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘 ...

  7. SICAU-OJ: 第k小

    第k小 题意: 给出一个长度不超过5000的字符串,然后让你找出第K小的字串(1<=K<=5).重复的串大小相等. 题解: 这里我们知道某些串的前缀是肯定小于等于其本身的. 那么长度为5的 ...

  8. java禁止实例化的工具类

    public class Q { /** * @param args */ public static void main(String[] args) { new Person() } } clas ...

  9. springboot中 后端跨域的实现配置

    在springboot的启动文件中,添加此内容,可以允许跨域

  10. 【转载】How long is “too long” for MySQL Connections to sleep?

    From:http://dba.stackexchange.com/questions/1558/how-long-is-too-long-for-mysql-connections-to-sleep ...