UVaLive2572 poj1418 UVa1308 Viva Confetti

一次放下n个圆

问最终可见的圆的数量

应该是比较经典的问题吧

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

将其割成了O(n)条弧

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

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

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

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<iostream>
  6 #include<cmath>
  7 #include<vector>
  8
  9 using namespace std;
 10
 11 typedef double data_type;
 12
 13 const data_type eps = 5 * 1e-13;
 14 int dcmp(const data_type& x) {
 15     if(fabs(x) < 0) return 0; return x < 0 ? -1 : 1;
 16 }
 17
 18 const data_type pi = acos(-1.0), dpi = 2 * acos(-1.0);
 19
 20 double NormalizeAngle(double rad) {
 21     return rad - dpi * floor(rad / dpi);
 22 }
 23
 24 typedef const struct Point& Point_cr;
 25 typedef struct Point {
 26     data_type x, y;
 27     Point() {}
 28     Point(data_type x, data_type y) : x(x), y(y) {}
 29     Point operator + (Point_cr rhs) const {
 30         return Point(x + rhs.x, y + rhs.y);
 31     }
 32     Point operator - (Point_cr rhs) const {
 33         return Point(x - rhs.x, y - rhs.y);
 34     }
 35     Point operator * (data_type k) const {
 36         return Point(x * k, y * k);
 37     }
 38     Point operator / (double k) const {
 39         return Point(x / k, y / k);
 40     }
 41     double length() const {
 42         return hypot(x, y);
 43     }
 44     double angle() const {
 45         return atan2(y, x);
 46     }
 47 }Vector;
 48
 49 double Dot(const Vector& v1, const Vector& v2) {
 50     return v1.x * v2.x + v1.y * v2.y;
 51 }
 52
 53 double length(const Vector& v) {
 54     return sqrt(Dot(v, v));
 55 }
 56
 57 typedef const Vector& Vector_cr;
 58 void CircleCircleIntersection(Point_cr c1, double r1, Point c2, double r2, vector<double> &rad) {
 59     double d = (c1 - c2).length();
 60     if(dcmp(d) == 0) return;
 61     if(dcmp(r1 + r2 - d) < 0) return;
 62     if(dcmp(fabs(r1 - r2) - d) > 0) return;
 63     double a = (c2 - c1).angle();
 64     double da = acos((r1 * r1 + d * d - r2 * r2) / (2 * r1 * d));
 65     rad.push_back(NormalizeAngle(a + da));
 66     rad.push_back(NormalizeAngle(a - da));
 67 }
 68
 69 const int N = 100 + 10;
 70 int n;
 71 Point centre[N];
 72 double radius[N];
 73 bool vis[N];
 74
 75 int topmost(Point p) {
 76     for(int i = n - 1; i >= 0; i--) {
 77         if((centre[i] - p).length() < radius[i]) return i;
 78     }
 79     return -1;
 80 }
 81
 82 int main() {
 83 #ifdef DEBUG
 84     freopen("in.txt", "r", stdin);
 85     freopen("out.txt", "w", stdout);
 86 #endif
 87
 88     while(scanf("%d", &n) == 1 && n) {
 89         for(int i = 0; i < n; i++) {
 90             double x, y, r;
 91             scanf("%lf%lf%lf", &x, &y, &r);
 92             centre[i] = Point(x, y);
 93             radius[i] = r;
 94         }
 95         memset(vis, 0, sizeof vis);
 96         for(int i = 0; i < n; i++) {
 97             vector<double> rad;
 98             rad.push_back(0);
 99             rad.push_back(dpi);
100
101             for(int j = 0; j < n; j++) {
102                 CircleCircleIntersection(centre[i], radius[i], centre[j], radius[j], rad);
103             }
104
105             sort(rad.begin(), rad.end());
106
107             for(unsigned j = 0; j < rad.size(); j++) {
108                 double mid = (rad[j] + rad[j+1]) / 2.0;
109                 for(int side = -1; side <= 1; side += 2) {
110                     double r2 = radius[i] - side * eps;
111                     int t = topmost(Point(centre[i].x + cos(mid) * r2, centre[i].y + sin(mid) * r2));
112                     if(t >= 0) vis[t] = 1;
113                 }
114             }
115         }
116         int ans = 0;
117         for(int i = 0; i < n; i++) if(vis[i]) {
118             ans++;
119         }
120         printf("%d\n", ans);
121     }
122
123     return 0;
124 }

时间: 2024-08-07 12:05:03

UVaLive2572 poj1418 UVa1308 Viva Confetti的相关文章

poj1418 Viva Confetti 判断圆是否可见

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Viva Confetti Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 881   Accepted: 361 Description Do you know confetti? They are small discs of colored paper, and people throw them a

uva 1308 - Viva Confetti(几何)

题目链接:uva 1308 - Viva Confetti 枚举一下两圆,处理出所有弧,然后判断每段弧的中点是否可见,可见的话该弧所在的圆也可见,以及该段弧下面的圆也可见. #include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> using namespace std; const double pi = 4 * at

Viva Confetti(几何+圆盘覆盖问题)

Viva Confetti Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 2572 Appoint description:  System Crawler  (2015-04-19) Description Do you know confetti? They are small discs of colored paper, and p

ZOJ 1696 Viva Confetti 计算几何

计算几何:按顺序给n个圆覆盖,问最后可以有几个圆被看见... 对每个圆求和其他圆的交点,每两个交点之间就是可能被看到的圆弧,取圆弧的中点,往外扩展一点或者往里缩一点,从上往下判断有没有圆可以盖住这个点,能盖住这个点的最上面的圆一定是可见的 Viva Confetti Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know confetti? They are small discs of colored paper, and p

POJ 1418 圆的基本操作以及 圆弧离散化

Viva Confetti Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 761   Accepted: 319 Description Do you know confetti? They are small discs of colored paper, and people throw them around during parties or festivals. Since people throw lots

挑战程序设计竞赛 3.6 与平面和空间打交道的计算几何

POJ 1981:Circle and Points /* 题目大意:给出平面上一些点,问一个半径为1的圆最多可以覆盖几个点 题解:我们对于每个点画半径为1的圆,那么在两圆交弧上的点所画的圆,一定可以覆盖这两个点 我们对于每个点计算出其和其它点的交弧,对这些交弧计算起末位置对于圆心的极角, 对这些我们进行扫描线操作,统计最大交集数量就是答案. */ #include <cstdio> #include <algorithm> #include <cmath> #incl

Nike Kyrie 4 &quot;Confetti&quot; Pefromance Reviews

Now the  Nike Kyrie 4 "Confetti" the colorful pair was released today .  and the Christmas holiday is coming , a lot of people  would like to buy this one as the gift . and now that Kyrie Irving has said goodbye to his third sneaker, so maybe th

Monkey测试

1             概述 Monkey测试是Android自动化测试的一种手段.Monkey测试本身非常简单,就是模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常. 当Monkey程序在模拟器或真实设备运行的时候,程序会产生一定数量或一定时间内的随机模拟用户操作的事件, 如点击,按键,手势等, 以及一些系统级别的事件.通常也称随机测试或者稳定性测试. 2             测试步骤 2.1   测试前提条件 1.将手机恢复出厂设置 2.恢复出厂设置后,进入设置--

使用 Core Animation 实现图片的碎片化----

用 Core Animation 实现图片的碎片化 参考书籍: 效果如下: 原理其实非常简单哦:). 1. 创建一个CALayer,使用其 contents 属性来装载一张图片(获取图片的CGImage) 2. 根据frame值裁剪图片,然后将裁剪的图片赋给你创建的更小的CALayer 3. 实现这些更小的CALayer的动画 4. 剩下的该干嘛干嘛,比如使用 Core Image 滤镜什么的,就靠你创造了:) 核心代码: 源码(书中提供,并非本人所写): /*** * Excerpted fr