UVa 10969 (圆与圆之间的覆盖问题) Sweet Dream
题意:
有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的更多相关文章
- cocos2d-x JS 各类点、圆、矩形之间的简单碰撞检测
这里总结了一下点.圆.矩形之间的简单碰撞检测算法 (ps:矩形不包括旋转状态) 点和圆的碰撞检测: 1.计算点和圆心的距离 2.判断点与圆心的距离是否小于圆的半 isCollision: functi ...
- UVa 10674 (求两圆公切线) Tangents
题意: 给出两个圆的圆心坐标和半径,求这两个圆的公切线切点的坐标及对应线段长度.若两圆重合,有无数条公切线则输出-1. 输出是按照一定顺序输出的. 分析: 首先情况比较多,要一一判断,不要漏掉. 如果 ...
- UVA 10382 - Watering Grass【贪心+区间覆盖问题+高精度】
UVa 10382 - Watering Grass n sprinklers are installed in a horizontal strip of grass l meters long a ...
- hdu4063(圆与圆交+线段与圆交+最短路)
写几何题总是提心吊胆.精度问题真心吓人. 其实思路挺简单的一道题,真是什么算法和几何double搞到一块,心里就虚虚的. 思路:求出所有圆之间的交点,然后用这些交点跑一遍最短路就可以了. Aircra ...
- 【BZOJ】2289: 【POJ Challenge】圆,圆,圆
题解 二分一个横坐标,过这个横坐标做一条和y轴平行的直线,相当于在这条直线上做区间覆盖,如果区间有交的话,那么答案是True 否则的话取两个不相交的区间,如果这两个圆相离或相切则不合法 否则看看相交的 ...
- bzoj2289: 【POJ Challenge】圆,圆,圆
Description 1tthinking随便地画了一些圆. ftiasch认为这些圆有交集(面积非零)的可能性不大.因为他实在画了太多圆,所以你被请来判断是否存在交集. Input 第1行,一个整 ...
- Ural 1332 把圆细分+圆内切,内含关系判定
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1332 #include<cstdio> #include<cstrin ...
- UVA - 11214 Guarding the Chessboard (可重复覆盖,DLX+IDA*)
题目链接 正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~ 每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX.注意要用IDA*来优化,否则会超时. #include ...
- UVA - 1603 Square Destroyer (DLX可重复覆盖+IDA*)
题目链接 给你一个n*n的由火柴组成的正方形网格,从中预先拿掉一些火柴,问至少还需要拿掉多少火柴才能破坏掉所有的正方形. 看到这道题,我第一反应就是——把每根火柴和它能破坏掉的正方形连边,不就是个裸的 ...
随机推荐
- Module模式 - 深入了解Javascript
/* Modelu模式 优点:效率高,代码少,加载速度快,松耦合允许并行加载,提升下载速度 缺点:初始化时间久一点 */ //一.基础用法 var calculate = function (eq) ...
- apache + tomcat 集群
apache2.2与tomcat集成(可以多个tomcat) 需求概况: 有3个服务: localhost:9091, localhost:9190. localhost:9191分别对应3个tomc ...
- IntelliJ IDEA的Maven项目在修改时报java.lang.OutOfMemoryError: PermGen space异常
什么也不说了---内存溢出,遇见太多回了,下面是解决方式: 1.在项目设置中新建Maven,然后设置VM: 2. 在pom.xml添加下面2个插件,一个是jrebel的,一个是jetty的 <b ...
- 输入一个链表,输出该链表中倒数第k个结点。
// test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- JNI中使用cl命令生成DLL文件
问题描述: 在使用JNI调用DLL时,首先需要生成DLL文件 问题解决: (1)现在使用VS2008的cl.exe程序,生成DLL文件 (1.1)cl.exe环境搭建 注: cl. ...
- linux常用命令详解
Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令.要想真正理解Linux系统, ...
- 【转】KM匹配题集
转自:http://blog.csdn.net/shahdza/article/details/7779324 [HDU]2255 奔小康赚大钱 模板题★1533 Going Home 模板题★242 ...
- iframe标签用法详解(属性、透明、自适应高度)(总结)
<iframe src="http://www.jb51.net" width="200" height="500"> 脚本之家 ...
- **bootstrap常见常用样式总结
1.水平居中 用 .text-center 类
- CTSC2016&&APIO2016游记
4.30 下午衡中放假,我们因为比赛的缘故提前到中午12:00放假 然后我爸爸说要来接我,直到下午两点多他才到,然后衡中宿舍的楼管阿姨死活不给我开门 莫名其妙的等到了三点多快四点的时候我才跟实验班的一 ...