题意

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. jdbc封装代码

    jdbc封装代码 package jdbcUtil; import java.sql.Connection; import java.sql.DriverManager; import java.sq ...

  2. VRChat简易教程2-创建一个最基本的世界(world)

    一.准备工作 1 先确保你安装了unity并导入了sdk 教程:https://www.cnblogs.com/cation/p/10311702.html 2 按之前的教程新建一个project并导 ...

  3. SpringBoot 表单验证

    Valid 注解 JSR 303 校验框架注解类: • @NotNull 注解元素必须是非空 • @Null 注解元素必须是空 • @Digits 验证数字构成是否合法 • @Future 验证是否在 ...

  4. mysql分库分表(一)

    mysql分库分表 参考: https://blog.csdn.net/xlgen157387/article/details/53976153 https://blog.csdn.net/cleve ...

  5. Effective C++ 条款06:若不想使用编译器自动生成的函数,就该明确拒绝

    规则一 将成员函数声明为private而且故意不实现他们 class HomeForSale { public: ... private: ... HomeForSale(const HomeForS ...

  6. UniquePaths,UniquePaths2,路径问题。动态规划。

    UniquePaths:给定m*n矩阵,从(0,0)到(m-1,n-1)路径条数.只能向下向右走. 算法分析:这和爬楼梯问题很像,到(m,n)的路径数是到(m-1,n)和(m,n-1)路径和.第一行, ...

  7. JNI简单步骤01

    1.环境变量 1.1.相应的环境变量中,加入如下内容:(Windows) (1).ClASSPATH中输入 : ".;C:\Program Files\Java\jdk1.7.0_07\jr ...

  8. glance cache

    用在多个glance API server 中,对相同的image文件提供服务.该cache对用户透明. 配置文件有一个image_cache_max_size,超过的话image cache会被修剪 ...

  9. 使用SpringMVC的crud操作时,进行数据修改,但是修改成功后,页面无法显示lastName属性值(被修改的那条记录)

    我这个错误的原因在于,把map的键写错了,它必须和类名第一个字母小写相同 @ModelAttribute public void getEmployee(@RequestParam(value=&qu ...

  10. 20165332实验一 Java开发环境的熟悉

    实验一 Java开发环境的熟悉 一.Java开发环境的熟悉-1 1.实验要求: 0 参考实验要求: 1 建立"自己学号exp1"的目录 : 2 在"自己学号exp1&qu ...