zoukankan      html  css  js  c++  java
  • [SPOJ]CIRU 圆并

    存代码

    新的编程方法? 基本过程依赖于对象?

    View Code
      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cmath>
      5 using namespace std;
      6 const int N = 1100;
      7 const double eps = 1e-8, PI = 3.14159265358979;
      8 int n;bool v[N];
      9 inline double sqr (double x) {return x * x; }
     10 inline int dcmp (double x) { return x < -eps ? -1 : x > eps; }
     11 struct vec {
     12     double x, y;
     13     vec () {}
     14     vec (double _x, double _y) : x (_x), y (_y) {}
     15 
     16     double dot (const vec & a) { return x * a.x + y * a.y; }
     17     double cross (const vec & a) { return x * a.y - y * a.x; }
     18     double len () { return sqrt (x * x + y * y); }
     19     vec pull (double t) {
     20         return vec (x * t, y * t);
     21     }
     22     vec rot (double cos, double sin) {
     23         //printf ("%lf %lf\n", x * cos + y * sin, x * -sin + y * cos);
     24         return vec (x * cos + y * sin, x * -sin + y * cos); }
     25 };
     26 typedef vec point;
     27 inline vec operator - (const point & a, const point & b)
     28 {
     29     return vec (a.x - b.x, a.y - b.y);
     30 }
     31 inline point operator + (const point & a, const vec & b)
     32 {
     33     return point (a.x + b.x, a.y + b.y);
     34 }
     35 struct Q {
     36     double val;
     37     point A;
     38     int sign;
     39     Q () {}
     40     Q (double _val, const point & _A, int _sign) { val = _val; A = _A; sign = _sign; }
     41     bool operator < (const Q & a) const {
     42         return val < a.val;
     43     }
     44 }a[N];
     45 typedef pair<Q, Q> pi;
     46 #define X first
     47 #define Y second
     48 struct ciru {
     49     double r;
     50     point o;
     51     void scan () { scanf ("%lf%lf%lf", &o.x, &o.y, &r); }
     52     void print () { printf ("%lf %lf %lf\n", o.x, o.y, r); }
     53     double dis (const ciru & a){
     54         return (o - a.o).len ();
     55     }
     56     bool in (const ciru & a){
     57         return dcmp (a.r - r - this->dis (a)) >= 0;
     58     }
     59     bool out (const ciru & a){
     60         return dcmp (this->dis (a) - (a.r + r)) >= 0;
     61     }
     62     pi G (const ciru & a)
     63     {
     64         vec oo = a.o - o;
     65         double d = oo.len ();
     66         double cos = (sqr (r) + sqr (d) - sqr (a.r)) / (2 * r * d);
     67         vec t1 = oo.rot (cos, sqrt (1 - sqr (cos))).pull (r / d);
     68         vec t2 = oo.rot (cos, -sqrt (1 - sqr (cos))).pull (r / d);
     69         //printf ("%lf %lf %lf\n", t1.x, t1.y, atan2 (t1.y, t1.x));
     70         //printf ("%lf %lf %lf\n", t2.x, t2.y, atan2 (t2.y, t2.x));
     71         //puts ("**************************");
     72         double t;
     73         return pi (Q ((t = atan2 (t1.y, t1.x)) < 0 ? t + 2 * PI : t, o + t1, 1), 
     74                    Q ((t = atan2 (t2.y, t2.x)) < 0 ? t + 2 * PI : t, o + t2, -1));
     75     }
     76 }cir[N];
     77 inline bool check (int x)
     78 {
     79     for (int i = 1; i <= n; i ++)
     80     {
     81         if (i == x || v[i]) continue;
     82         if (cir[x].in (cir[i]))
     83             return true;
     84     }
     85     return false;
     86 }
     87 inline double area (Q & a, const Q & b, double r)
     88 {
     89     double t = b.val - a.val;
     90     //printf ("%lf\n", sqr (r) * (t - sin (t)) + a.A.cross (b.A));
     91     return 0.5 * sqr (r) * (t - sin (t)) + 0.5 * a.A.cross (b.A);
     92 }
     93 inline double G (int x)
     94 { 
     95     int cnt = 0, now = 0;double S (0);pi tmp;point O;
     96     a[++ cnt].val = 0;
     97     O = a[cnt].A = cir[x].o + vec (cir[x].r, 0);
     98     a[cnt].sign = 0;
     99     a[++ cnt].val = 2 * PI;
    100     a[cnt].A = O;
    101     a[cnt].sign = 0;
    102     for (int i = 1; i <= n; i ++)
    103     {
    104         if (i == x || cir[x].out (cir[i])) continue;
    105         tmp = cir[x].G (cir[i]);
    106         a[++ cnt] = tmp.X;
    107         a[++ cnt] = tmp.Y;
    108         if (a[cnt - 1].val > a[cnt].val)
    109             a[++ cnt] = Q (0, O, 1), a[++ cnt] = Q (2 * PI, O, -1);
    110     }
    111     sort (a + 1, a + 1 + cnt);
    112     for (int i = 1; i < cnt; i ++)
    113     {
    114         now += a[i].sign;
    115         if (now == 0)
    116             S += area (a[i], a[i + 1], cir[x].r);
    117     }
    118     return S;
    119 }
    120 int main ()
    121 {
    122     //freopen ("a.in", "r", stdin);
    123     //freopen ("a.out", "w", stdout);
    124     scanf ("%d", &n);
    125     for (int i = 1; i <= n; i ++)
    126         cir[i].scan ();
    127     for (int i = 1; i <= n; i ++)
    128         if (dcmp (cir[i].r) == 0)
    129             v[i] = true;
    130     for (int i = 1; i <= n; i ++)
    131     {
    132         if (v[i]) continue;
    133         v[i] = check (i);
    134     }
    135     for (int i = n; i >= 1; i --)
    136         if (v[i])
    137         {
    138             n --;
    139             for (int j = i + 1; j <= n + 1; j ++)
    140                 cir[j - 1] = cir[j];
    141         }
    142     /*printf ("%d\n", n);
    143     for (int i = 1; i <= n; i ++)
    144         cir[i].print ();*/
    145     
    146     double S (0);
    147     for (int i = 1; i <= n; i ++)
    148         S += G (i);
    149     printf ("%.3lf\n", S);
    150     return 0;        
    151 }
  • 相关阅读:
    Windows共享上网的做法
    如何花更少的时间学习更多的知识
    因权限引起的svn提交失败的错误及其解决办法
    ArcGIS二次开发入门(一)
    GeoTiff如何存储颜色表的研究
    html5文件夹上传源码
    vue文件夹上传源码
    前端文件夹上传源码
    asp.net文件夹上传源码
    使用webuploader实现大文件上传分片上传
  • 原文地址:https://www.cnblogs.com/tellmewtf/p/2915059.html
Copyright © 2011-2022 走看看