题意

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. Nginx进阶-不停服更新

    前言 7*24小时不间断的提供对外服务和产品快速迭代是互联网行业的特征,基于需求所有的发布都不能停止当前对外的服务.本文围绕此话题衍生出,不停服上下线工具实现. 看本文前请先看 Nginx初识 Ten ...

  2. shell自动化一键部署脚本,秒级一键回滚脚本

    #!/bin/bash # Node List PRE_LIST="192.168.222.163" # 预生产环境节点 GROUP1_LIST= ROLLBACK_LIST=&q ...

  3. Oracle sql plus中常用的几个命令

    1.set linesize 300(表示一行为300个字符) set linesize可以设置一行显示的字符数,默认情况下为80个字符 2.l(list) 可以显示缓冲区中的最后执行的内容 3.ru ...

  4. Rreact Native 常见错误总结

    1.invariant violation:expected a component class,got[object object]        创建自定义组件首字母要大写,否则会报错.     ...

  5. 用maven创建web工程

    1.打开eclipse,选择File->New->Other菜单,弹出下面的对话框,在Wizards中输入maven,会过滤出和maven相关的菜单,选中Maven Project菜单,然 ...

  6. tcp连接的建立与释放

    1.TCP是面向连接的协议. 运输连接时用来传送TCP报文的.TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程.因此,运输链接就有三个阶段,即:连接建立.数据传送和连接释放. 在TCP ...

  7. struts2——上传图片格式

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  8. idea调节字体大小

    这是调节前的 这是调节后的 步骤

  9. static变量的作用

    在C语言中,关键字static的意思是静态的,有3个明显的作用: 1. 在函数体内,静态变量具有记忆作用,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变. 2. 在模块内(但在函数体外) ...

  10. windows8.1下安装Cygwin并通过apt-cyg安装软件包

    参考 http://yuanshuilee.blog.163.com/blog/static/2176972752014126786185/ http://www.cnblogs.com/zhang- ...