• HDU 1883 Phone Cell(计算几何)


      方法:选取一个点A,以点A为圆心做一个半径为r的圆,然后枚举另一个点B,以B为圆心做一个圆,如果这两个圆有交集,那我们在这个交集内选取一个点做半径为r的圆,这个圆就包括了A和B点,找到交集最多的区域并计算这个区域被覆盖的次数,把这个数加一就是最多能够覆盖的点个数,枚举所有的A,就可以得到最优解,剩下我想说的都在下面的图里,代码里也有相关注释;

      这个题在比赛的时候我们并没有做出来,赛后看了题解才知道,由于作者的代码风格很好,所以不做修改,下面是作者的原博客地址:

    http://www.cnblogs.com/CSGrandeur/archive/2012/09/10/2678682.html

      下面这个图片有助于理解代码

    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <iostream>
    #include <algorithm> using namespace std ; const double eps = 1e-8; const double PI = acos(-1.0) ; int n ; double r ; struct point { double x,y ;
    } p[
    2010] ; struct node { double angle ; int flag ; } q[5000] ; int dcmp(double d) { return d < -eps ? -1 : d > eps ; } bool cmp(const node &a,const node &b)///角度区间排序,区间上限永远在上; { if(dcmp(a.angle-b.angle) == 0 ) return a.flag > b.flag ;
    return a.angle < b.angle ; } double Cal(double x) { return x*x ; } double dist(const point &a,const point &b) { return sqrt(Cal(a.x-b.x)+Cal(a.y-b.y)) ; } int main() { while(~scanf("%d%lf",&n,&r)) { if(n == 0) break ; for(int i = 0 ; i < n ; i++) scanf("%lf%lf",&p[i].x,&p[i].y) ;
    int ans = 0,m = 0; for(int i = 0 ; i < n ; i++) { m = 0 ; for(int j = 0 ; j < n ; j++) { if(i == j) continue ; double d = dist(p[i],p[j]) ; if(d > 2*r+0.001) continue ; double s = atan2(p[j].y-p[i].y,p[j].x-p[i].x) ; ///atan2 和 atan 的区别; ///1:参数的填写方式不同; ///2:atan2 的优点在于 如果 x2-x1等于0 依然可以计算,但是atan函数就会导致程序出错; if(s < 0) s += 2*PI ;///角度区间修正 double ph = acos(d/2.0/r) ;///圆心角转区间 q[m++].angle = s - ph + 2*PI ;///图中b-a,避免负值+2*PI; q[m-1].flag = 1 ;///标记为上界
    q[m
    ++].angle = s + ph + 2*PI ;///图中a+b; q[m-1].flag = -1 ;///标记下界 } sort(q,q+m,cmp) ; int sum = 0 ; for(int j = 0 ; j < m ; j++)///这种记录区间最大交集次数的方式很巧妙,当时我对这里还是挺困惑的,读者若不懂应稍加思考. ans = max(ans,sum += q[j].flag) ; } /*for(int j = 0; j < m; j++) { cout<<"angle = "<<q[j].angle<<endl; cout<<"flag = "<<q[j].flag<<endl; }*/ printf("It is possible to cover %d points. ",ans+1) ; } return 0 ; }
  • 相关阅读:
    Lc112_路径总和
    多线程(4)
    Lc257_二叉树的所有路径
    Lc226_翻转二叉树
    Lc145_二叉树的后序遍历
    Lc144_二叉树的前序遍历
    Lc102_二叉树的层序遍历
    Lc101_对称二叉树
    Lc100_相同的树
    Lc94_二叉树的中序遍历
  • 原文地址:https://www.cnblogs.com/jifahu/p/5456801.html
Copyright © 2020-2023  润新知