这个题目的方法是将圆盘分成一个个圆环,然后判断这些圆环是否被上面的圆覆盖;

如果这个圆的圆周上的圆弧都被上面的覆盖,暂时把它标记为不可见;

然后如果他的头上有个圆,他有个圆弧可见,那么他自己本身可见,并且可以把这条圆弧下面的第一个圆重新标记为可见;

另外,圆弧可见还是不可见利用它的中点来进行判断;

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; const int maxn = + ;
const double eps = 1e-; //别开太大,样例数据就到达1e-11级别
const double pi = acos(-); int dcmp(double x)
{
return fabs(x) < eps ? : (x > ? : -);
} struct Point
{
double x;
double y; Point(double x = , double y = ):x(x), y(y) {} bool operator < (const Point& e) const
{
return dcmp(x - e.x) < || (dcmp(x - e.x) == && dcmp(y - e.y) < );
} bool operator == (const Point& e) const
{
return dcmp(x - e.x) == && dcmp(y - e.y) == ;
} int read()
{
return scanf("%lf%lf", &x, &y);
}
}; typedef Point Vector; Vector operator + (Point A, Point 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 * (Point A, double p)
{
return Vector(A.x * p, A.y * p);
} Vector operator / (Point A, double p)
{
return Vector(A.x / p, A.y / p);
} struct Circle
{
Point c;
double r; Circle() {}
Circle(Point c, double r):c(c), r(r) {} int read()
{
return scanf("%lf%lf%lf", &c.x, &c.y, &r);
} Point point(double a)
{
return Point(c.x + r * cos(a), c.y + r * sin(a));
}
}; 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);
} bool PointInCircle(Point p, Circle C) //判断点是否在圆内
{
double dist = Length(p - C.c);
if(dcmp(dist - C.r) > ) return ; //这里我选择点在圆边上不算在圆内
else return ;
} bool CircleInCircle(Circle A, Circle B) //判断圆在圆内
{
double cdist = Length(A.c - B.c);
double rdiff = B.r - A.r;
if(dcmp(A.r - B.r) <= && dcmp(cdist - rdiff) <= ) return ; //包括重合,内切和内含的情况
return ;
} int n;
Circle C[maxn];
bool vis[maxn];
vector<double> pointAng[maxn]; int GetCircleCircleIntersection(int c1, int c2) //求圆与圆的交点
{
Circle C1 = C[c1];
Circle C2 = C[c2];
double d = Length(C1.c - C2.c);
if(dcmp(d) == )
{
if(dcmp(C1.r - C2.r) == ) return -; //两圆重合
return ; //同心圆但不重合
}
if(dcmp(C1.r + C2.r - d) < ) return ; //外离
if(dcmp(fabs(C1.r - C2.r) - d) > ) return ; //内含
double a = angle(C2.c - C1.c);
double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / ( * C1.r * d));
Point p1 = C1.point(a + da);
Point p2 = C1.point(a - da);
if(p1 == p2) return ; //相切
pointAng[c1].push_back(a + da); //相切的点不处理,只要相交的
pointAng[c1].push_back(a - da);
return ;
} void init()
{
for(int i = ; i < n; i++) pointAng[i].clear();
memset(vis, , sizeof(vis));
} void read()
{
for(int i = ; i < n; i++) C[i].read();
} void solve()
{
for(int i = ; i < n; i++) //圆两两相交,得各圆交点集合
for(int j = ; j < n; j++) if(i != j)
GetCircleCircleIntersection(i, j);
for(int i = ; i < n; i++)
{
sort(pointAng[i].begin(), pointAng[i].end()); //各圆交点按极角排序
vector<double>::iterator iter = unique(pointAng[i].begin(), pointAng[i].end()); //去重,可减少运行时间,不去重也能AC
pointAng[i].resize(distance(pointAng[i].begin(), iter));
}
for(int i = ; i < n; i++) //判断第i个圆上的弧
{
int sz = pointAng[i].size();
if(!sz) //此圆不与其他圆相交
{
bool ok = ;
for(int k = i+; k < n; k++) if(CircleInCircle(C[i], C[k])) //判上面是否有圆把它覆盖掉
{
ok = ;
break;
}
if(ok) vis[i] = ;
}
else
{
pointAng[i].push_back(pointAng[i][]);
for(int j = ; j < sz; j++) //第i个圆上的第j条弧
{
bool ok = ;
Point pm = C[i].point((pointAng[i][j] + pointAng[i][j+]) / ); //取弧的中点
for(int k = i+; k < n; k++) if(PointInCircle(pm, C[k]))
{
ok = ;
break;
}
if(ok)
{
vis[i] = ;
for(int u = i-; u >= ; u--)if(PointInCircle(pm, C[u])) //把这段圆弧下的圆设为可见
{
vis[u] = ;
break;
}
}
}
}
}
int ret = ;
for(int i = ; i < n; i++) if(vis[i]) ret++;
printf("%d\n", ret);
} int main()
{
while(scanf("%d", &n) == && n)
{
init();
read();
solve();
}
return ;
}

uva 1308 - Viva Confetti的更多相关文章

  1. uva 2572 Viva Confetti

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

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

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

  3. poj 1418 Viva Confetti

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

  4. ZOJ 1696 Viva Confetti 计算几何

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

  5. UVaLive2572 poj1418 UVa1308 Viva Confetti

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

  6. LA2572 Viva Confetti

    题意 PDF 分析 两两圆求交点,对每个圆弧按半径抖动. 时间复杂度\(O(T n^2)\) 代码 #include<iostream> #include<cstdio> #i ...

  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. uva 1354 Mobile Computing ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5

随机推荐

  1. hdu1016JAVA

    import java.util.Arrays;import java.util.Scanner;public class Main { public static int kase=0,n; pub ...

  2. iOS中使用nil NULL NSNULL的区别

    nil NULL NSNULL的区别主要以下几点 1.nil:一般赋值给空对象 2.NLL:一般赋值给nil之外的其他空值.入SEL等. 3.NSULL:NSNULL只有一种方法+ (NSNull * ...

  3. verilog语法:进程名

    always @ (posedge clk, negedge rstn)begin:State_flipflops if(!rstn) y<=S1; else y<=Y;end请问这段程序 ...

  4. portal单点登录的原理与实现还有ESB

    portal单点登录的原理与实现还有ESB 在毕业论文中有描述到这一点.我给我出的截图

  5. ABI Management

    官方文档:https://developer.android.com/ndk/guides/abis.html?hl=is 关于支持指令集,在上表官方文档都表达清楚了.我们认为避免多个指令集浪费资源. ...

  6. c# linq 基础知识点

    1.Where与TakeWhile,Where和sql中的where一样,返回所有满足条件的元素,而TakeWhile判断原理类似于while语句,从头逐个判断,只要条件为真就一直返回检索到的元素,只 ...

  7. Xcode6.1模拟器ios8.1模拟器不能弹出虚拟键盘及虚拟键盘无法切换中文输入的解决办法

    1.不能弹出虚拟键盘的解决办法 模拟器菜单Hardware->Keyboard->Connect Hardware Keyboard取消选中,快捷键commad+shift+K 2.虚拟键 ...

  8. js hashMap

    /** * MAP对象,实现MAP功能 * * 接口: * size() 获取MAP元素个数 * isEmpty() 判断MAP是否为空 * clear() 删除MAP所有元素 * put(key, ...

  9. Top命令查看内存

    c 切换显示命令名称和完整命令行. M 根据驻留内存大小进行排序 第四行:内存状态 8306544k total — 物理内存总量(8GB) 7775876k used — 使用中的内存总量(7.7G ...

  10. ubuntu netbeans compile ygopro client with google protobuf lib

    environment: ubuntu 16.04 netbeans 8.2 ygopro Fluorohydride with Irrlicht Game Engine 问题1: google pr ...