zoukankan      html  css  js  c++  java
  • CF886F Symmetric Projections

    题意:给你平面上n个点,问有多少条过原点的直线,使得这些点在该直线上的投影(做垂直,对应点)形成对称图形?n<=2000。

    标程:

     1 #include<bits/stdc++.h>
     2 #define P pair<int,int>
     3 using namespace std;
     4 const int inf=0x3f3f3f3f;
     5 const double eps=1e-8;
     6 const int N=2005;
     7 struct node{double x,y,k;int px,py;}a[N*N];
     8 double mid_x,mid_y;
     9 int n,x[N],y[N],ans,k,t,p[N],die[N],X[N],Y[N],cnt,lst,pos;
    10 bool cmp (const node &A,const node &B) {return A.k<B.k;}
    11 bool operator == (const node &A,const node &B) {return A.x*B.y==A.y*B.x;}
    12 bool check(int x,double b1,double b2)//double不要开成int! 
    13 {
    14     double dx=mid_y-Y[x],dy=-mid_x+X[x];
    15     return fabs(dy*b1-b2*dx)<eps;
    16 }
    17 int main()
    18 {
    19     scanf("%d",&n);
    20     for (int i=1;i<=n;i++) 
    21       scanf("%d%d",&x[i],&y[i]),mid_x+=x[i],mid_y+=y[i]; 
    22     mid_x/=n;mid_y/=n;
    23     for (int i=1;i<n;i++)
    24     if (!die[i])
    25       for (int j=i+1;j<=n;j++)
    26         if (!die[j]&&fabs(x[i]+x[j]-2*mid_x)<eps&&fabs(y[i]+y[j]-2*mid_y)<eps) {die[i]=die[j]=1;break;}
    27     for (int i=1;i<=n;i++) if (!die[i]) X[++t]=x[i],Y[t]=y[i];
    28     if (t<2) return puts("-1"),0;
    29     for (int i=1;i<t;i++)
    30       for (int j=i+1;j<=t;j++)
    31       {
    32            double dx=mid_y-(Y[i]+Y[j])/2.0,dy=-mid_x+(X[i]+X[j])/2.0;//垂直,斜率负倒数
    33            if (dx<0) dx=-dx,dy=-dy; 
    34            if (dx==0) dy=fabs(dy);
    35            if (dy==0) dx=fabs(dx);//!!!
    36            a[++cnt].x=dx,a[cnt].y=dy;a[cnt].px=i;a[cnt].py=j;a[cnt].k=atan2(dy,dx);
    37       }
    38     sort(a+1,a+cnt+1,cmp);lst=1;
    39     for (int i=1;i<=cnt;i++)//check and count 
    40       if (i==cnt||!(a[i]==a[i+1]))
    41       {
    42             if (i-lst+1>=t/2) 
    43             {
    44                 for (int j=1;j<=t;j++) p[j]=1;
    45                 for (;lst<=i;lst++) 
    46                   if (p[a[lst].px]&&p[a[lst].py]) p[a[lst].px]=p[a[lst].py]=0;//注意重合的两点不能同时和另一点匹配!一配一 
    47                 k=0;
    48                 for (int j=1;j<=t;j++) if (p[j]) k++,pos=j;
    49                 if (k>(t&1)) continue; 
    50                 if (!k||check(pos,a[i].x,a[i].y)) ans++;
    51             } 
    52             lst=i+1; 
    53       }
    54     printf("%d
    ",ans);
    55    return 0;
    56 }

    易错点:1.double不要开成int

    2.比较斜率相等的时候,不要比较k关键字,直接用x和y关键字的乘积比较即可。由于最多带小数0.5,所以不会有误差, 直接==即可。

    题解:计算几何

    一开始的想法是坐标系旋转解旋转角。

    正解如下,

    找到该图形的重心,易证不管怎么旋转,对称轴一定经过重心。

    如果一对点关于重心对称,那么不管怎么旋转这两个点到对称轴的距离都相等,匹配上,删去。

    由此发现剩下来的点,n^2枚举两个点作为对称点,有且仅有一条直线满足这两个点的投影在其上关于经过重心的直线对称。

    check直线是否符合条件:

    如果一条相同斜率的直线出现次数>=n/2,那么说明有足够多的对称点对在其上。看是否能否匹配完所有点,如果n是偶数一定能匹配完,n是奇数会多出一个看是否恰好在对称轴上。

    时间复杂度O(n^2)。

  • 相关阅读:
    Selenium简单测试页面加载速度的性能(Page loading performance)
    Selenium Page object Pattern usage
    Selenium如何支持测试Windows application
    UI Automation的两个成熟的框架(QTP 和Selenium)
    分享自己针对Automation做的两个成熟的框架(QTP 和Selenium)
    敏捷开发中的测试金字塔(转)
    Selenium 的基础框架类
    selenium2 run in Jenkins GUI testing not visible or browser not open but run in background浏览器后台运行不可见
    eclipse与SVN 结合(删除SVN中已经上传的问题)
    配置Jenkins的slave节点的详细步骤适合windows等其他平台
  • 原文地址:https://www.cnblogs.com/Scx117/p/9085940.html
Copyright © 2011-2022 走看看