uva 2572 Viva Confetti
思路:
小圆面是由小圆弧围成。那么找出每条小圆弧,如果小圆弧,在小圆弧中点上下左右进行微小位移的所得的点一定在一个小圆面内。
找到最后覆盖这个小点的圆一定是可见的。
圆上的点按照相邻依次排序的关键量为极角(0,2PI)
用中心点代替圆弧本身是否被圆覆盖
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<memory.h>
#include<cstdlib>
#include<vector>
#define clc(a,b) memset(a,b,sizeof(a))
#define LL long long int
#define up(i,x,y) for(i=x;i<=y;i++)
#define w(a) while(a)
using namespace std;
const int inf=0x3f3f3f3f;
const int N = ;
const double eps = *1e-;
const double pi = acos(-); int dcmp(double x)
{
if(fabs(x) < eps) return ;
else return x < ? - : ;
} const double PI = acos(-);
const double TWO_PI = PI * ; double NormalizeAngle(double rad, double center = PI)
{
return rad - TWO_PI * floor((rad + PI - center) / TWO_PI);
} struct Point
{
double x, y;
Point(double x=, double y=):x(x),y(y) { }
}; typedef Point Vector; Vector operator + (Vector A, Vector B)
{
return Vector(A.x+B.x, A.y+B.y);
}
Vector operator - (Point A, Point B)
{
return Vector(A.x-B.x, A.y-B.y);
}
Vector operator * (Vector A, double p)
{
return Vector(A.x*p, A.y*p);
}
Vector operator / (Vector A, double p)
{
return Vector(A.x/p, A.y/p);
} double Dot(Vector A, Vector B)
{
return A.x*B.x + A.y*B.y;
}
double Length(Vector A)
{
return sqrt(Dot(A, A));
} double angle(Vector v)
{
return atan2(v.y, v.x);
} // 交点相对于圆1的极角保存在rad中
void getCircleCircleIntersection(Point c1, double r1, Point c2, double r2, vector<double>& rad)
{
double d = Length(c1 - c2);
if(dcmp(d) == ) return; // 不管是内含还是重合,都不相交
if(dcmp(r1 + r2 - d) < ) return;
if(dcmp(fabs(r1-r2) - d) > ) return; double a = angle(c2 - c1);
double da = acos((r1*r1 + d*d - r2*r2) / (*r1*d));
rad.push_back(NormalizeAngle(a-da));
rad.push_back(NormalizeAngle(a+da));
} const int maxn = + ;
int n;
Point center[maxn];
double radius[maxn];
bool vis[maxn]; // 覆盖点p的最上层的圆
int topmost(Point p)
{
for(int i = n-; i >= ; i--)
if(Length(center[i]-p) < radius[i]) return i;
return -;
} int main()
{
while(cin >> n)
{
if(!n) break;
for(int i = ; i < n; i++)
{
double x, y, r;
cin >> x >> y >> r;
center[i] = Point(x, y);
radius[i] = r;
}
memset(vis, , sizeof(vis));
for(int i = ; i < n; i++)
{
// 考虑圆i被切割成的各个圆弧。把圆周当做区间来处理,起点是0,终点是2PI
vector<double> rad;
rad.push_back();
rad.push_back(PI*);
for(int j = ; j < n; j++)
getCircleCircleIntersection(center[i], radius[i], center[j], radius[j], rad);
sort(rad.begin(), rad.end()); for(int j = ; j < rad.size(); j++)
{
double mid = (rad[j] + rad[j+]) / 2.0; // 圆弧中点相对于圆i圆心的极角
for(int side = -; side <= ; side += )
{
double r2 = radius[i] - side*eps; // 往里面或者外面稍微一动一点点
int t = topmost(Point(center[i].x + cos(mid)*r2, center[i].y + sin(mid)*r2));
if(t >= ) vis[t] = true;
}
}
}
int ans = ;
for(int i = ; i < n; i++) if(vis[i]) ans++;
cout << ans << "\n";
}
return ;
}
uva 2572 Viva Confetti的更多相关文章
- uva 1308 - Viva Confetti
这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖: 如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见: 然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见, ...
- poj1418 Viva Confetti 判断圆是否可见
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Viva Confetti Time Limit: 1000MS Memory ...
- poj 1418 Viva Confetti
Viva Confetti Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1025 Accepted: 422 Desc ...
- ZOJ 1696 Viva Confetti 计算几何
计算几何:按顺序给n个圆覆盖.问最后能够有几个圆被看见.. . 对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这 ...
- UVaLive2572 poj1418 UVa1308 Viva Confetti
一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...
- LA2572 Viva Confetti
题意 PDF 分析 两两圆求交点,对每个圆弧按半径抖动. 时间复杂度\(O(T n^2)\) 代码 #include<iostream> #include<cstdio> #i ...
- [GodLove]Wine93 Tarining Round #9
比赛链接: http://vjudge.net/contest/view.action?cid=48069#overview 题目来源: lrj训练指南---二维几何计算 ID Title Pro ...
- POJ 1418 基本操作和圆 离散弧
Viva Confetti Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 761 Accepted: 319 Descr ...
- UVa 10969 (圆与圆之间的覆盖问题) Sweet Dream
题意: 有n个按先后顺序放置的不同大小不同位置的圆,求所有可见圆弧的长度. 分析: 这道题应该是大白书上例题 LA 2572 (求可见圆盘的数量) Kanazawa 的加强版,整体框架都差不多. 对于 ...
随机推荐
- JavaScript中创建字典对象(dictionary)实例
这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...
- 【贪心】 BZOJ 3252:攻略
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 261 Solved: 90[Submit][Status][Discuss] De ...
- Maven SDK
Maven SDK Details Print Tags: development maven maven2 liferay v6.0 Table of Contents [-] Introdu ...
- iOS利用HealthKit框架从健康app中获取步数信息
微信和QQ的每日步数最近十分火爆,我就想为自己写的项目中添加一个显示每日步数的功能,上网一搜好像并有相关的详细资料,自己动手丰衣足食. 统计步数信息并不需要我们自己去实现,iOS自带的健康app已经为 ...
- Android 签名(3)已签名的apk中的文件
已经签名 apk包中签名相关的文件在meta_INF目录下 CERT.SF:生成每个文件相对的密钥 MANIFEST.MF:数字签名信息 xxx.SF:这是JAR文件的签名文件,占位符xxx标识了签名 ...
- 安装win7 32位系统出现的问题解决办法
计算机意外地重新启动或遇到错误.Windows 安装无法继续.若要安装Windows,请单击“确定”重新启动计算机,然后重新启动安装”. http://www.baidusoso.net/ ...
- Hive QL 介绍
小结 本次课程学习了 Hive QL 基本语法和操作. 一.实验环境说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou,密码shiyanlou 2. 环境介绍 本实验环境采用带桌面的 ...
- 函数innobase_start_or_create_for_mysql
buffer pool初始化 /******************************************************************** Starts InnoDB a ...
- bzoj列表2
之前发过一次了,这里的题较水,没什么好讲的 bzoj1088 直接穷举前两位即可,话说程序员的扫雷是白玩的? bzoj1083 裸的最小生成树(最小生成树=最小瓶颈树),SCOI大丈夫(话说网上二分是 ...
- apache开源项目--TIKA
Tika是一个内容抽取的工具集合(a toolkit for text extracting).它集成了POI, Pdfbox 并且为文本抽取工作提供了一个统一的界面.其次,Tika也提供了便利的扩展 ...