• POJ 1981 定长圆覆盖最多点


    题意:

    一些点,求一个单位圆最多能覆盖的点的个数,不存在两点距离恰好为2.

    题解:

    暴力枚举两个点,求圆心,然后枚举每个点验证是否在圆内。n^3的,可以过~

    当然还有n^2logn的转化为求圆的最大弧的覆盖次数问题(以后做CIRU 的时候也会用到这个技术~)

    n^3

    View Code
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 
      8 #define N 333
      9 #define EPS 1e-7
     10 #define PI 3.141592653589793238
     11 #define INF 1e10
     12 
     13 using namespace std;
     14 
     15 struct PO
     16 {
     17     double x,y;
     18     void prt() {printf("%lf      %lf\n",x,y);}
     19 }p[N];
     20 
     21 int n,ans;
     22 
     23 const double r=1.0;
     24 
     25 inline void read()
     26 {
     27     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
     28 }
     29 
     30 inline PO operator +(PO a,PO b)
     31 {
     32     PO c;
     33     c.x=a.x+b.x; c.y=a.y+b.y;
     34     return c;
     35 }
     36 
     37 inline PO operator -(PO a,PO b)
     38 {
     39     PO c;
     40     c.x=a.x-b.x; c.y=a.y-b.y;
     41     return c;
     42 }
     43 
     44 inline int dc(double x)
     45 {
     46     if(x>EPS) return 1;
     47     else if(x<-EPS) return -1;
     48     return 0;
     49 }
     50 
     51 inline double getdis2(PO &a,PO &b)
     52 {
     53     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
     54 }
     55 
     56 inline double getlen(PO &a)
     57 {
     58     return sqrt(a.x*a.x+a.y*a.y);
     59 }
     60 
     61 inline PO rotate(PO a)
     62 {
     63     PO ans;
     64     ans.x=a.y;
     65     ans.y=-a.x;
     66     return ans;
     67 }
     68 
     69 inline PO geto(PO &a,PO &b)
     70 {
     71     PO mid=a+b;
     72     mid.x/=2; mid.y/=2;
     73     PO ab=b-a;
     74     double len=getlen(ab);
     75     ab.x/=len; ab.y/=len;
     76     ab=rotate(ab);
     77     len=sqrt(r-len*len*0.25);
     78     ab.x*=len; ab.y*=len;
     79     return mid+ab;
     80 }
     81 
     82 inline void check(PO &o)
     83 {
     84     int res=0;
     85     for(int i=1;i<=n;i++)
     86         if(dc(getdis2(p[i],o)-r)<=0) res++;
     87     ans=max(res,ans);
     88 }
     89 
     90 inline void go()
     91 {
     92     ans=1;PO o;
     93     for(int i=1;i<=n;i++)
     94         for(int j=i+1;j<=n;j++)
     95             if(dc(getdis2(p[i],p[j])-4*r)<=0)
     96             {
     97                 o=geto(p[i],p[j]);
     98                 check(o);
     99                 o=geto(p[j],p[i]);
    100                 check(o);
    101             }
    102     printf("%d\n",ans);
    103 }
    104 
    105 int main()
    106 {
    107     while(scanf("%d",&n),n) read(),go();
    108     return 0;
    109 }

    n^2logn

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <cstdlib>
      5 #include <cstdio>
      6 #include <algorithm>
      7 
      8 #define N 777
      9 #define PI 3.141592653589
     10 #define EPS 1e-7
     11 
     12 using namespace std;
     13 //定长圆覆盖最多点,转为最大弧覆盖次数 
     14 struct C
     15 {
     16     double x,y,r;
     17     void prt() {printf("%lf      %lf\n",x,y);}
     18 }c[N];
     19 
     20 struct T
     21 {
     22     int fg;
     23     double ag;
     24     void prt() {printf("%lf     %d\n",ag,fg);}
     25 }t[N<<2];
     26 
     27 int n,cnt,ans;
     28 double ccd,r=1.0;
     29 
     30 inline int dc(double x)
     31 {
     32     if(x>EPS) return 1;
     33     else if(x<-EPS) return -1;
     34     return 0;
     35 }
     36 
     37 inline C operator +(C a,C b)
     38 {
     39     C tmp;
     40     tmp.x=a.x+b.x; tmp.y=a.y+b.y;
     41     return tmp;
     42 }
     43 
     44 inline C operator -(C a,C b)
     45 {
     46     C tmp;
     47     tmp.x=a.x-b.x; tmp.y=a.y-b.y;
     48     return tmp;
     49 }
     50 
     51 inline C operator *(C a,double k)
     52 {
     53     a.x*=k; a.y*=k;
     54     return a;
     55 }
     56 
     57 inline C operator /(C a,double k)
     58 {
     59     a.x/=k; a.y/=k;
     60     return a;
     61 } 
     62 
     63 inline void read()
     64 {
     65     for(int i=1;i<=n;i++)
     66     {
     67         scanf("%lf%lf",&c[i].x,&c[i].y);
     68         c[i].r=1.0;
     69     }
     70 }
     71 
     72 inline bool cmp(const T &a,const T &b)
     73 {
     74     if(dc(a.ag-b.ag)==0) return a.fg>b.fg;
     75     return a.ag<b.ag;
     76 }
     77 
     78 inline double getdis(const C &a,const C &b)
     79 {
     80     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     81 }
     82 
     83 inline C getf(const C &a,const C &b)//单位法向量 
     84 {
     85     C tmp=b-a; tmp=tmp/ccd;
     86     C ans;
     87     ans.x=-tmp.y; ans.y=tmp.x;
     88     return ans;
     89 }
     90 
     91 inline void getcpoint(const C &c1,const C c2,C &a,C &b)
     92 {
     93     double cs=(c2.r*c2.r+ccd*ccd-c1.r*c1.r)/(2*ccd);
     94     double cp=ccd-cs;
     95     double hh=sqrt(c1.r*c1.r-cp*cp);
     96     C f=getf(c1,c2);
     97     f=f*hh;
     98     a=((c2-c1)*cp/ccd-f);
     99     b=((c2-c1)*cp/ccd+f);
    100 }
    101 
    102 inline void go()
    103 {
    104     ans=0;
    105     C o1,o2;
    106     for(int i=1;i<=n;i++)
    107     {
    108         cnt=0;
    109         for(int j=1;j<=n;j++)
    110         {
    111             if(i==j) continue;
    112             ccd=getdis(c[i],c[j]);
    113             if(dc(ccd-2*r)>0) continue;
    114             getcpoint(c[i],c[j],o1,o2);
    115             double ag1=atan2(o1.y,o1.x);
    116             double ag2=atan2(o2.y,o2.x);
    117             if(dc(ag1)>0&&dc(ag2)<=0)//跨越x轴负半轴,拆开 
    118             {
    119                 t[++cnt].fg=1; t[cnt].ag=ag1;
    120                 t[++cnt].fg=-1; t[cnt].ag=PI;
    121                 t[++cnt].fg=1; t[cnt].ag=-PI;
    122                 t[++cnt].fg=-1; t[cnt].ag=ag2;
    123             }
    124             else 
    125             {
    126                 t[++cnt].fg=1; t[cnt].ag=ag1;
    127                 t[++cnt].fg=-1; t[cnt].ag=ag2;
    128             }
    129         }
    130         sort(t+1,t+1+cnt,cmp);
    131         int res=0;
    132         for(int j=1;j<=cnt;j++)
    133         {
    134             res+=t[j].fg;
    135             ans=max(ans,res);
    136         }
    137     }
    138     printf("%d\n",ans+1);
    139 }
    140 
    141 int main()
    142 {
    143     while(scanf("%d",&n),n) read(),go();
    144     return 0;
    145 }
  • 相关阅读:
    数据结构入门
    C语言入门-全局变量
    C语言入门-类型定义
    C++ 名称空间嵌套
    C++ 名称空间
    C++ 一些术语
    C++ new初始化与定位new运算符
    网络时间自动同步工具
    C++ 语言链接性
    C++ 函数和链接性
  • 原文地址:https://www.cnblogs.com/proverbs/p/2937950.html
Copyright © 2020-2023  润新知