题意:

有n个按先后顺序放置的不同大小不同位置的圆,求所有可见圆弧的长度。

分析:

这道题应该是大白书上例题 LA 2572 (求可见圆盘的数量) Kanazawa 的加强版,整体框架都差不多。

对于每个圆求出与其他圆相交的交点所对应的幅角(转化到[0, 2π]中),排个序,然后枚举每段弧的终点,如果不被后面放置的圆所覆盖则可见。

注意:

原本以为WA是精度问题,后来调大调小都一直WA,这里精度eps从1e-11到1e-13都没问题。

但是在判断弧的终点是否被圆所覆盖的时候要加上等号。也就是第64行代码中是<=而非<,一直被这个给坑惨了。

UVa的数据真的好强啊,Orz

 #include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std; const int maxn = + ;
const double eps = 1e-;
const double PI = acos(-1.0);
const double TWO_PI = 2.0 * PI;
double radius[maxn]; double NormalizeAngle(double ang)
{ return ang - TWO_PI*floor(ang/TWO_PI); } int dcmp(double x)
{
if(fabs(x) < eps) return ;
return x < ? - : ;
} struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y) {}
}p[maxn];
typedef Point Vector; bool operator == (const Point& A, const Point& B)
{ return dcmp(A.x - B.x) == && dcmp(A.y - B.y) == ; } Point operator - (const Point& A, const Point& B)
{ return Point(A.x - B.x, A.y - B.y); } double Dot(const Point& A, const Point& B)
{ return A.x*B.x + A.y*B.y; } double Length(const Vector& A)
{ return sqrt(Dot(A, A)); } double Angle(const Vector& A)
{ return atan2(A.y, A.x); } void GetCCIntersection(const Point& c1, double r1, const Point& c2, double r2, vector<double>& rad)
{
double d = Length(c1 - c2);
if(dcmp(d) == ) return;
if(dcmp(d-r1-r2) > ) return;
if(dcmp(d-fabs(r1-r2)) < ) return; double base = Angle(c2 - c1);
double ang = acos((r1*r1 + d*d - r2*r2) / (2.0*r1*d));
rad.push_back(NormalizeAngle(base + ang));
rad.push_back(NormalizeAngle(base - ang));
} int n; bool isVisible(const Point& C, int id)
{
for(int i = id + ; i < n; ++i)
{
double d = Length(C - p[i]);
if(dcmp(d - radius[i]) <= ) return false; //这道题的关键所在
}
return true;
} int main(void)
{
//freopen("10969in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = ; i < n; ++i) scanf("%lf%lf%lf", &radius[i], &p[i].x, &p[i].y); double sum = 0.0;
for(int i = ; i < n; ++i)
{
vector<double> rad;
rad.push_back(0.0);
rad.push_back(TWO_PI);
for(int j = ; j < n; ++j)
{
if(j == i) continue;
GetCCIntersection(p[i], radius[i], p[j], radius[j], rad);
}
sort(rad.begin(), rad.end()); for(int j = ; j < rad.size() - ; ++j)
{
double mid = (rad[j] + rad[j + ]) / ;
double ang = rad[j + ] - rad[j];
Point C(p[i].x + radius[i]*cos(mid), p[i].y + radius[i]*sin(mid));
if(isVisible(C, i)) sum += radius[i] * ang;
}
} printf("%.3f\n", sum);
} return ;
}

代码君

UVa 10969 (圆与圆之间的覆盖问题) Sweet Dream的更多相关文章

  1. cocos2d-x JS 各类点、圆、矩形之间的简单碰撞检测

    这里总结了一下点.圆.矩形之间的简单碰撞检测算法 (ps:矩形不包括旋转状态) 点和圆的碰撞检测: 1.计算点和圆心的距离 2.判断点与圆心的距离是否小于圆的半 isCollision: functi ...

  2. UVa 10674 (求两圆公切线) Tangents

    题意: 给出两个圆的圆心坐标和半径,求这两个圆的公切线切点的坐标及对应线段长度.若两圆重合,有无数条公切线则输出-1. 输出是按照一定顺序输出的. 分析: 首先情况比较多,要一一判断,不要漏掉. 如果 ...

  3. UVA 10382 - Watering Grass【贪心+区间覆盖问题+高精度】

    UVa 10382 - Watering Grass n sprinklers are installed in a horizontal strip of grass l meters long a ...

  4. hdu4063(圆与圆交+线段与圆交+最短路)

    写几何题总是提心吊胆.精度问题真心吓人. 其实思路挺简单的一道题,真是什么算法和几何double搞到一块,心里就虚虚的. 思路:求出所有圆之间的交点,然后用这些交点跑一遍最短路就可以了. Aircra ...

  5. 【BZOJ】2289: 【POJ Challenge】圆,圆,圆

    题解 二分一个横坐标,过这个横坐标做一条和y轴平行的直线,相当于在这条直线上做区间覆盖,如果区间有交的话,那么答案是True 否则的话取两个不相交的区间,如果这两个圆相离或相切则不合法 否则看看相交的 ...

  6. bzoj2289: 【POJ Challenge】圆,圆,圆

    Description 1tthinking随便地画了一些圆. ftiasch认为这些圆有交集(面积非零)的可能性不大.因为他实在画了太多圆,所以你被请来判断是否存在交集. Input 第1行,一个整 ...

  7. Ural 1332 把圆细分+圆内切,内含关系判定

    题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1332 #include<cstdio> #include<cstrin ...

  8. UVA - 11214 Guarding the Chessboard (可重复覆盖,DLX+IDA*)

    题目链接 正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~ 每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX.注意要用IDA*来优化,否则会超时. #include ...

  9. UVA - 1603 Square Destroyer (DLX可重复覆盖+IDA*)

    题目链接 给你一个n*n的由火柴组成的正方形网格,从中预先拿掉一些火柴,问至少还需要拿掉多少火柴才能破坏掉所有的正方形. 看到这道题,我第一反应就是——把每根火柴和它能破坏掉的正方形连边,不就是个裸的 ...

随机推荐

  1. 利用JavaScript获取页面文档内容

    JavaScript的document对象包含了页面的实际内容,所以利用document对象可以获取页面内容,例如页面标题.各个表单值. <!DOCTYPE html> <html ...

  2. JQuery,UIbootstrap风格弹出层

    <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <met ...

  3. 使用函数的递归调用来解决Hanoi(汉诺)塔问题。

    #include<stdio.h> void hanoi(int n, char x, char y, char z); void move(char x, char y); int ti ...

  4. 01-06-01【Nhibernate (版本3.3.1.4000) 出入江湖】事务

    Nhibernate事务的使用: public void Add(Customer customer) { ISession session = _sessionManager.GetSession( ...

  5. uva 11235

    数据结构 RMQ算法   左右左右   写得有点晕了 ..... /****************************************************************** ...

  6. Unity3d Detect NetState

    public static bool HasConnection() { System.Net.WebClient client; System.IO.Stream stream; try { usi ...

  7. Create a method synchronized without using synchronized keyword

    Actually, lots of ways: No need for synchronization at all if you don't have mutable state. No need ...

  8. Oracle函数+for循环

    create or replace function FilterMinganci(str in varchar) return varchar2 is filterWorld varchar2(10 ...

  9. POJ2418Hardwood Species

    题意 : 输入若干个树木品种,里边有的是重复的,让你统计每个品种占输入的总数量的百分比,最后按字典序输出 思路 : 本题数量很大,所以采用直接统计的方式会超时,而采用的方法可以用二叉搜索树,或者用ma ...

  10. hdu 2177 取(2堆)石子游戏 博弈论

    由于要输出方案,变得复杂了.数据不是很大,首先打表,所有whthoff 的奇异局势. 然后直接判断是否为必胜局面. 如果必胜,首先判断能否直接同时相减得到.这里不需要遍历或者二分查找.由于两者同时减去 ...