• hdu 1077 (圆交)


    Problem - 1077

      我们可以知道,当这个单位圆可以覆盖到最多的点的时候,必定最少有两个点位于这个圆的圆周上,于是就有网上众多的O(N^3)的枚举两个在圆上的点的暴搜做法。

      然而这题是可以用圆交来做的。

      我们以一条鱼的位置作为圆心,半径为1的圆的周围随便找一个点都能把这条鱼抓到。这时,我们可以做出很多个这样的圆,半径都为1。

      然后,求一下这些圆的交集,叠起来的最高层数就是最多能获得的鱼的数目。

      这里的圆交不需要实现求面积这部分,于是只需要离散一下交点就行了。

      1y。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <iomanip>
      6 #include <cmath>
      7 
      8 using namespace std;
      9 
     10 const double EPS = 1e-8;
     11 const double PI = acos(-1.0);
     12 inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
     13 template<class T> T sqr(T x) { return x * x;}
     14 typedef pair<double, double> Point;
     15 #define x first
     16 #define y second
     17 
     18 Point operator + (Point a, Point b) { return Point(a.x + b.x, a.y + b.y);}
     19 Point operator - (Point a, Point b) { return Point(a.x - b.x, a.y - b.y);}
     20 Point operator * (Point a, double p) { return Point(a.x * p, a.y * p);}
     21 Point operator * (double p, Point a) { return Point(a.x * p, a.y * p);}
     22 Point operator / (Point a, double p) { return Point(a.x / p, a.y / p);}
     23 
     24 inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;}
     25 inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;}
     26 inline double veclen(Point a) { return sqrt(dot(a, a));}
     27 inline double angle(Point a) { return atan2(a.y, a.x);}
     28 inline Point vecunit(Point a) { return a / veclen(a);}
     29 inline Point normal(Point a) { return Point(-a.y, a.x) / veclen(a);}
     30 
     31 struct Line {
     32     Point s, t;
     33     Line() {}
     34     Line(Point s, Point t) : s(s), t(t) {}
     35     Point vec() { return t - s;}
     36     Point point(double p) { return s + vec() * p;}
     37 } ;
     38 inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));}
     39 
     40 struct Circle {
     41     Point c;
     42     double r;
     43     Circle() {}
     44     Circle(Point c, double r) : c(c), r(r) {}
     45     Point point(double p) { return c + r * Point(cos(p), sin(p));}
     46     bool in(Point p) { return sgn(veclen(p - c) - r) < 0;}
     47 } ;
     48 
     49 const double R = 1000.0;
     50 const int N = 333;
     51 int n;
     52 Circle cir[N];
     53 
     54 void input() {
     55     cin >> n;
     56     for (int i = 0; i < n; i++) {
     57         cin >> cir[i].c.x >> cir[i].c.y;
     58         cir[i].c = cir[i].c * R;
     59         cir[i].r = R;
     60     }
     61 }
     62 
     63 bool ccint(int _a, int _b, double *sol) {
     64     Circle a = cir[_a], b = cir[_b];
     65     double d = veclen(a.c - b.c), dr = fabs(a.r - b.r);
     66     if (sgn(d - a.r - b.r) > 0) return 0;
     67     if (sgn(dr - d) >= 0) {
     68         if (a.r < b.r || sgn(a.r - b.r) == 0 && _a < _b) {
     69             sol[0] = -PI;
     70             sol[1] = PI;
     71             return 1;
     72         }
     73         return 0;
     74     }
     75     double ang = angle(b.c - a.c);
     76     double da = acos(fabs(sqr(a.r) + sqr(d) - sqr(b.r)) / (2 * a.r * d));
     77     sol[0] = ang - da;
     78     sol[1] = ang + da;
     79     return 1;
     80 }
     81 
     82 typedef pair<double, int> Event;
     83 Event ev[N << 1];
     84 bool cmp(Event a, Event b) {
     85     if (sgn(a.x - b.x)) return a.x < b.x;
     86     return a.y > b.y;
     87 }
     88 
     89 int cal(int id) {
     90     int tt = 0;
     91     double _[2];
     92     for (int i = 0; i < n; i++) {
     93         if (i == id) continue;
     94         if (ccint(id, i, _)) {
     95             if (_[0] < -PI) {
     96                 ev[tt++] = Event(_[0] + 2 * PI, 1);
     97                 ev[tt++] = Event(PI, -1);
     98                 ev[tt++] = Event(-PI, 1);
     99                 ev[tt++] = Event(_[1], -1);
    100             } else if (_[1] > PI) {
    101                 ev[tt++] = Event(_[0], 1);
    102                 ev[tt++] = Event(PI, -1);
    103                 ev[tt++] = Event(-PI, 1);
    104                 ev[tt++] = Event(_[1] - 2 * PI, -1);
    105             } else {
    106                 ev[tt++] = Event(_[0], 1);
    107                 ev[tt++] = Event(_[1], -1);
    108             }
    109         }
    110     }
    111     int cnt = 1, mx = 1;
    112     sort(ev, ev + tt, cmp);
    113     for (int i = 0; i < tt; i++) {
    114         cnt += ev[i].y;
    115         mx = max(mx, cnt);
    116     }
    117     return mx;
    118 }
    119 
    120 int work() {
    121     int mx = 0;
    122     for (int i = 0; i < n; i++) mx = max(mx, cal(i));
    123     return mx;
    124 }
    125 
    126 int main() {
    127     //freopen("in", "r", stdin);
    128     ios::sync_with_stdio(0);
    129     cout << setiosflags(ios::fixed) << setprecision(5);
    130     int _;
    131     cin >> _;
    132     while (_--) {
    133         input();
    134         cout << work() << endl;
    135     }
    136     return 0;
    137 }
    View Code

    ——written by Lyon

  • 相关阅读:
    从零开始~
    SVN
    了解下几个证书~~
    重要的技术发展趋势
    求职路上英语面试试题问答大全
    C语言比java重要吗?
    开源solr搜索服务器配置
    全文索引 与 Like 的实现原理
    nginx搭建多个站点
    .Solr构建索引查询索引
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_1077_Lyon.html
Copyright © 2020-2023  润新知