LA2572 Viva Confetti
题意
分析
两两圆求交点,对每个圆弧按半径抖动。
时间复杂度\(O(T n^2)\)
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0;
rg int w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>T read(T&x)
{
return x=read<T>();
}
using namespace std;
typedef long long ll;
co double eps=5e-13;
int dcmp(double x)
{
if(fabs(x)<0)
return 0;
else
return x<0?-1:1;
}
co double PI=acos(-1);
double NormalizeAngle(double rad,double center=PI)
{
return rad-PI*2*floor((rad+PI-center)/(PI*2));
}
struct Point
{
double x,y;
Point(double x=0,double y=0)
:x(x),y(y){}
double angle()
{
return atan2(y,x);
}
};
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));
}
void CircleCircleIntersection(Point c1,double r1,Point c2,double r2,vector<double>&rad)
{
double d=Length(c1-c2);
if(dcmp(d)==0)
return;
if(dcmp(r1+r2-d)<0)
return;
if(dcmp(fabs(r1-r2)-d)>0)
return;
double a=(c2-c1).angle();
double da=acos((r1*r1+d*d-r2*r2)/(2*r1*d));
rad.push_back(NormalizeAngle(a-da));
rad.push_back(NormalizeAngle(a+da));
}
co int N=100;
int n;
Point center[N];
double radius[N];
bool vis[N];
int topmost(Point p)
{
for(int i=n-1;i>=0;--i)
if(dcmp(Length(center[i]-p)-radius[i])<0)
return i;
return -1;
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
while(read(n))
{
for(int i=0;i<n;++i)
scanf("%lf %lf %lf",¢er[i].x,¢er[i].y,&radius[i]);
fill(vis,vis+n,0);
for(int i=0;i<n;++i)
{
vector<double>rad;
rad.push_back(0);
rad.push_back(PI*2);
for(int j=0;j<n;++j)
CircleCircleIntersection(center[i],radius[i],center[j],radius[j],rad);
sort(rad.begin(),rad.end());
for(int j=0;j<rad.size();++j)
{
double mid=(rad[j]+rad[j+1])/2;
for(int side=-1;side<=1;side+=2)
{
double r2=radius[i]-side*eps;
int t=topmost(Point(center[i].x+cos(mid)*r2,center[i].y+sin(mid)*r2));
if(t>=0)
vis[t]=1;
}
}
}
int ans=0;
for(int i=0;i<n;++i)
if(vis[i])
++ans;
printf("%d\n",ans);
}
return 0;
}
LA2572 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个圆覆盖.问最后能够有几个圆被看见.. . 对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这 ...
- uva 2572 Viva Confetti
思路: 小圆面是由小圆弧围成.那么找出每条小圆弧,如果小圆弧,在小圆弧中点上下左右进行微小位移的所得的点一定在一个小圆面内. 找到最后覆盖这个小点的圆一定是可见的. 圆上的点按照相邻依次排序的关键量为 ...
- uva 1308 - Viva Confetti
这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖: 如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见: 然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见, ...
- UVaLive2572 poj1418 UVa1308 Viva Confetti
一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...
- [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 ...
- Thesis Viva checklist
This list gives you suggestions helpful in preparing to defend your thesis: I know my thesis thoroug ...
随机推荐
- 一种BIM缺失多态性介导的酪氨酸激酶抑制剂的耐药性
论文名称:A common BIM deletion polymorphism mediates intrinsic resistance and inferior responses to tyro ...
- Android 在 SElinux下 如何获得对一个内核节点的访问权限【转】
本文转载自:https://blog.csdn.net/wh_19910525/article/details/45170755 Android 5.0下,因为采取了SEAndroid/SElinux ...
- 使用John the ripper工具来尝试破解Linux密码
这篇文章主要介绍了使用John the ripper工具来尝试破解Linux密码的方法,这款工具可能主要被用来破解系统用户的密码以获得文件操作权限,需要的朋友可以参考下 John有别于Hdra之类的工 ...
- centos7 部署 dotnetcore
一.在centos上下载dotnetcore SDK 二. 选择Linux发行版安装 按上面的步骤安装,在centos终端输入dotnet --version 显示版本信息即安装成功
- git branch 常用语句详解
删除远程分支 git push origin --delete <branchName> 查看本地分支 git branch 创建本地新分支 git branch <branchNa ...
- NumPy统计函数
NumPy - 统计函数 NumPy 有很多有用的统计函数,用于从数组中给定的元素中查找最小,最大,百分标准差和方差等. 函数说明如下: numpy.amin() 和 numpy.amax() 这些函 ...
- Android 中Json解析的几种框架(Gson、Jackson、FastJson、LoganSquare)使用与对比
介绍 移动互联网产品与服务器端通信的数据格式,如果没有特殊的需求的话,一般选择使用JSON格式,Android系统也原生的提供了JSON解析的API,但是它的速度很慢,而且没有提供简介方便的接口来提高 ...
- Mysql 索引复习笔记
之前学习索引后由于一直没怎么用,所以也只是粗略看了一下,最近发现索引的用处很大,并且也很多知识点,在此做复习记录. 什么是索引? 百度百科是这样描述的: 索引是为来加速对表中数据行中的检索而创建的一种 ...
- ie if判断
<p> </p> <!--[if lt IE 7]> <html lang="en" ng-app="myApp" c ...
- postgresql centos6.5安装以及常用命令
今天在centos6.5下安装postgresql数据库,现在整理自己操作步骤. 一. Centos6.5 下安装postgresql9.4 1.1. 显示所有的有关postgresql安装包 yum ...