zoukankan      html  css  js  c++  java
  • 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
    ", ans);
    121     }
    122     
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
    thinkphp整合系列之微信公众号支付
    JS之变量的运算
    (php)thinkphp3.2配置sql_server
    jyd数据结构
    mac终端下svn常用命令
    项目学习
    抛错
    phpunit
    Python
  • 原文地址:https://www.cnblogs.com/showson/p/5143533.html
Copyright © 2011-2022 走看看