一次放下n个圆

问最终可见的圆的数量

应该是比较经典的问题吧

考虑一个圆与其他每个圆的交点O(n)个

将其割成了O(n)条弧

那么看每条弧的中点 分别向内向外调动eps这个点 则最上面的覆盖这个点的圆可见O(n)

总时间复杂度O(n ** 3)

怕炸精度,代码基本抄的rjl的

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector> using namespace std; typedef double data_type; const data_type eps = * 1e-;
int dcmp(const data_type& x) {
if(fabs(x) < ) return ; return x < ? - : ;
} const data_type pi = acos(-1.0), dpi = * acos(-1.0); double NormalizeAngle(double rad) {
return rad - dpi * floor(rad / dpi);
} typedef const struct Point& Point_cr;
typedef struct Point {
data_type x, y;
Point() {}
Point(data_type x, data_type y) : x(x), y(y) {}
Point operator + (Point_cr rhs) const {
return Point(x + rhs.x, y + rhs.y);
}
Point operator - (Point_cr rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
Point operator * (data_type k) const {
return Point(x * k, y * k);
}
Point operator / (double k) const {
return Point(x / k, y / k);
}
double length() const {
return hypot(x, y);
}
double angle() const {
return atan2(y, x);
}
}Vector; double Dot(const Vector& v1, const Vector& v2) {
return v1.x * v2.x + v1.y * v2.y;
} double length(const Vector& v) {
return sqrt(Dot(v, v));
} typedef const Vector& Vector_cr;
void CircleCircleIntersection(Point_cr c1, double r1, Point c2, double r2, vector<double> &rad) {
double d = (c1 - c2).length();
if(dcmp(d) == ) return;
if(dcmp(r1 + r2 - d) < ) return;
if(dcmp(fabs(r1 - r2) - d) > ) return;
double a = (c2 - c1).angle();
double da = acos((r1 * r1 + d * d - r2 * r2) / ( * r1 * d));
rad.push_back(NormalizeAngle(a + da));
rad.push_back(NormalizeAngle(a - da));
} const int N = + ;
int n;
Point centre[N];
double radius[N];
bool vis[N]; int topmost(Point p) {
for(int i = n - ; i >= ; i--) {
if((centre[i] - p).length() < radius[i]) return i;
}
return -;
} int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif while(scanf("%d", &n) == && n) {
for(int i = ; i < n; i++) {
double x, y, r;
scanf("%lf%lf%lf", &x, &y, &r);
centre[i] = Point(x, y);
radius[i] = r;
}
memset(vis, , sizeof vis);
for(int i = ; i < n; i++) {
vector<double> rad;
rad.push_back();
rad.push_back(dpi); for(int j = ; j < n; j++) {
CircleCircleIntersection(centre[i], radius[i], centre[j], radius[j], rad);
} sort(rad.begin(), rad.end()); for(unsigned j = ; j < rad.size(); j++) {
double mid = (rad[j] + rad[j+]) / 2.0;
for(int side = -; side <= ; side += ) {
double r2 = radius[i] - side * eps;
int t = topmost(Point(centre[i].x + cos(mid) * r2, centre[i].y + sin(mid) * r2));
if(t >= ) vis[t] = ;
}
}
}
int ans = ;
for(int i = ; i < n; i++) if(vis[i]) {
ans++;
}
printf("%d\n", ans);
} return ;
}

UVaLive2572 poj1418 UVa1308 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. 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. Thesis Viva checklist

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

随机推荐

  1. 理解MySQL——索引与优化(转)

    写 在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页 面大小为4K,并存储100条记录.如果没有索引,查 ...

  2. ASP.Net定时任务执行

    原料: System.Timers.Timer():通过.NET  Thread  Pool实现的,轻量,计时精确,对应用程序.消息没有特别的要求:缺点是不支持直接的拖放,需要手工编码. Timer的 ...

  3. 对N个数组进行操作。先把这N个一维数组合并成一个2为数组;然后进行操作

    using System;using System.Collections.Generic;using System.Linq;using System.Collections;using Syste ...

  4. ubuntu 下截图工具的使用

    我个人觉得,ubuntu自带的截图工具功能就不错.具体使用如下: 在ubuntu下的系统设置中找到硬盘区的“键盘”处,进入该设置界面如下: 选择标签“快捷键”,进入新设置界面如下所示: 之后,你就可以 ...

  5. 关于微软RDLC报表打印时文字拉伸问题(Windows server 2003 sp2)

    最近我们开发的打印服务频频出现打印文字拉伸问题,客户意见络绎不绝,最为明显的是使用黑体加粗后 “2.0份” 打印出来后小数点几乎看不见了,用户很容易误认为 “ 20份” .所以问题达到了不得不停下手上 ...

  6. ARC - MRC

    1. 选择工程 ---> build phases  --> .m中添加 -fno-objc-arc

  7. [BZOJ 1034] [ZJOI2008] 泡泡堂BNB 【贪心】

    题目链接:BZOJ - 1034 题目分析 这道题和田忌赛马的典故很相似. 先要将两队的队员都按照水平从小到大分别排序. 然后每次尝试用我方最弱的队员赢对方最弱的队员,或者用我方最强的队员赢对方最强的 ...

  8. TCP三次握手和http过程

    pc浏览服务器网页此过程不包括域名查询,只描述TCP与http数据流的变化.一.pc与http服务器进行三次握手来建立连接.1.pc:seq=0 ack=0 syn=1 ack=0 发送给服务器建立同 ...

  9. Python on Android

    Python on Android Posted on April 29, 2015 by Alexander Taylor   There are an increasing number of r ...

  10. Nodejs异步

    http://cnodejs.org/topic/4f16442ccae1f4aa2700113b http://cnodejs.org/topic/4f16442ccae1f4aa27001123 ...