题意

PDF

分析

两两圆求交点,对每个圆弧按半径抖动。

时间复杂度\(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",&center[i].x,&center[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的更多相关文章

  1. poj1418 Viva Confetti 判断圆是否可见

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Viva Confetti Time Limit: 1000MS   Memory ...

  2. poj 1418 Viva Confetti

    Viva Confetti Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1025   Accepted: 422 Desc ...

  3. ZOJ 1696 Viva Confetti 计算几何

    计算几何:按顺序给n个圆覆盖.问最后能够有几个圆被看见.. . 对每一个圆求和其它圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下推断有没有圆能够盖住这 ...

  4. uva 2572 Viva Confetti

    思路: 小圆面是由小圆弧围成.那么找出每条小圆弧,如果小圆弧,在小圆弧中点上下左右进行微小位移的所得的点一定在一个小圆面内. 找到最后覆盖这个小点的圆一定是可见的. 圆上的点按照相邻依次排序的关键量为 ...

  5. uva 1308 - Viva Confetti

    这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖: 如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见: 然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见, ...

  6. UVaLive2572 poj1418 UVa1308 Viva Confetti

    一次放下n个圆 问最终可见的圆的数量 应该是比较经典的问题吧 考虑一个圆与其他每个圆的交点O(n)个 将其割成了O(n)条弧 那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆 ...

  7. [GodLove]Wine93 Tarining Round #9

    比赛链接: http://vjudge.net/contest/view.action?cid=48069#overview 题目来源: lrj训练指南---二维几何计算   ID Title Pro ...

  8. POJ 1418 基本操作和圆 离散弧

    Viva Confetti Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 761   Accepted: 319 Descr ...

  9. Thesis Viva checklist

    This list gives you suggestions helpful in preparing to defend your thesis: I know my thesis thoroug ...

随机推荐

  1. pycharm中创建并设置docker解释器

    在Windows上使用Docker的其中一个目的是使其与PyCharm结合,形成Python代码的解释器,避免重复的Python解释环境搭建的问题,同时保持Windows开发环境和部署环境所用的Pyt ...

  2. kali 源设置sources.list

    由于阿里源有些问题,可能我设置的问题,所以就去掉了,163的很快 # deb cdrom:[Debian GNU/Linux 2016.1 _Kali-rolling_ - Official Snap ...

  3. github Git-fork-别人的项目后更新代码的方法

     用github还处于菜的阶段,遇到问题简单记录.   举个例子,需要 fork 这个项目 https://github.com/tarobjtu/WebFundamentals.git 点击 for ...

  4. [C++] 2017联发科技杯编程挑战赛 复赛题 “杰克船长的烦恼”

    题目如下. 规则 杰克船长这次运气不错,抢到了一大堆金币.但他马上又开始发愁了, 因为如何给大家分金币,一直都是件不容易的事,每次杰克船长都要头疼好几天. 关于分金币,海盗的行规是这样的: 每次行动, ...

  5. java 使用反射

    java程序中的对象在运行时会出现两种类型:编译时类型和运行时类型.例如List list  = new ArrayList().其中变量list的编译时类型是List,运行时类型是ArrayList ...

  6. OpenStack Ceilometer -- 后台数据存储优化之MongoDB的分片存储设置

    https://xiaofandh12.github.io/Mongo-Shard 关于MongoDB MongoDB中的概念与关系型数据库之间的对应: Database --> Databas ...

  7. 从互信息的角度来理解tf-idf

    先介绍tf idf 在一份给定的文件里,词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率.这个数字是对词数(term count)的归一化,以防止它偏向长的文件.( ...

  8. mysql升级的一些踩坑点

    升级的方法一般有两类: 1.利用mysqldump来直接导出sql文件,导入到新库中,这种方法最省事也最保险 缺点:大库的mysqldump费时费力. 2.直接替换掉 mysql 的安装目录和 my. ...

  9. D3.js学习笔记(四)—— 使用SVG坐标空间

    目标 在这一章,你将要使用D3.js基于一些数据把SVG元素添加到你想要的坐标位置上. 我们的目标就是使用下面的数据集: var spaceCircles = [30,70,110]; 并使用D3.j ...

  10. selenium学习笔记(简单的元素定位)

    收拾一下心情开始新的一周工作 继续是selenium的学习.配置成功后 由于所有操作都是建立在页面元素基础上的.所以下来就是学习定位元素 首先是基础的定位.就使用博客园首页搜索框为例: 下面是代码: ...