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的由火柴组成的正方形网格,从中预先拿掉一些火柴,问至少还需要拿掉多少火柴才能破坏掉所有的正方形. 看到这道题,我第一反应就是——把每根火柴和它能破坏掉的正方形连边,不就是个裸的 ...
随机推荐
- java url中文参数乱码问题
http://www.blogjava.net/jerry-zhaoj/archive/2009/07/16/286993.html 转 JAVA 中URL链接中文参数乱码的处理方法JAVA 中URL ...
- Linux "ls -l"文件列表权限详解
ls Linux "ls -l"文件列表权限详解 1.使用 ls -l 命令 执行结果如下(/var/log) : drwxr-x--- root adm -- : apache2 ...
- Codeforces Round #327 (Div. 1) B. Chip 'n Dale Rescue Rangers 二分
题目链接: 题目 B. Chip 'n Dale Rescue Rangers time limit per test:1 second memory limit per test:256 megab ...
- Linux开机执行bash脚本
问题描述: Linux开机执行bash脚本 问题解决: (1)在 /etc/init.d文件夹中新建一个脚本myinit (2) ...
- jQuery基于ajax实现星星评论代码
本文实例讲述了jQuery基于ajax实现星星评论代码.分享给大家供大家参考.具体如下: 这里使用jquery模仿点评网的星星评论功能,Ajax评论模块,鼠标点击星星即可评价,下边是分数,可以点击后给 ...
- HDU 4101 Ali and Baba
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4101 一看之下以为是博弈,后来分析才知道只是搜索题. 首先,我们需要从值为-1的位置由内向外搜索一次, ...
- ios开发之数据存取1-SQLite
iOS开发中常用的数据存取方式有: XML属性列表-PList NSKeyedArchiver 归档 Preference-偏好设置 SQLite3 Core Data-以面向对象的方式操作数据库SQ ...
- String 内在分配解析
1.String类概念 (1)String是final的,不可被继承.public final class String.String是的本质是字符数组char[], 并且其值不可改变.private ...
- 【redis】02string类型和hash类型
Redis的数据类型 Redis主要分为五个数据类型,一个是string,最简单的一个数据类型,hash,list, 还有set集合,还有zset有序集合,这是咱们redis的五种基础类型, 接下 ...
- 适合我胃口的angular.js学习资料
断断续续弄了半年的ANGULAR.JS学习资料,网上下载了N多资料,测试了很多次. 现在只能算是入门,因时间问题,现在要转入其它领域. 如果以后要拾起来,下面这个PDF比较对我胃口. <Angu ...