zoukankan      html  css  js  c++  java
  • bzoj2592: [Usaco2012 Feb]Symmetry

    Description

    After taking a modern art class, Farmer John has become interested in finding geometric patterns in everything around his farm. He carefully plots the locations of his N cows (2 <= N <= 1000), each one occupying a distinct point in the 2D plane, and he wonders how many different lines of symmetry exist for this set of points. A line of symmetry, of course, is a line across which the points on both sides are mirror images of each-other. Please help FJ answer this most pressing geometric question.

    上过现代艺术课后,FJ开始感兴趣于在他农场中的几何图样。他计划将奶牛放置在二维平面上的N个互不相同的点(1<=N<=1000),他希望找出这个点集有多少条对称轴。他急切地需要你帮忙解决这个几何问题。

    Input

    * Line 1: The single integer N.

    * Lines 2..1+N: Line i+1 contains two space-separated integers representing the x and y coordinates of the ith cow (-10,000 <= x,y <= 10,000).

    Output

    * Line 1: The number of different lines of symmetry of the point set.

    圆上的整点很少,所以可以找出点集的重心并把点按到重心的距离排序,到重心相同距离的点在同一圆上,计算这些点的对称轴(最多四条),最后取交集即可,时间复杂度是O(n2logn)但因为整点且范围小所以不会达到最坏情况

    #include<bits/stdc++.h>
    typedef long double ld;
    const ld pi=std::acos(-1),_0=1e-7l;
    int n,ans=0,xs=0,ys=0,lp=0,ap=0,ad=0;
    struct pos{int x,y;long long d;ld a;}ps[1007];
    ld ls[2007],as[2007];
    bool operator<(pos a,pos b){
        return a.d!=b.d?a.d<b.d:a.a<b.a;
    }
    ld dis(ld x,ld y){
        return std::sqrt(x*x+y*y);
    }
    int fix(int a,int l,int r){
        if(a<l)return a+r-l;
        if(a>=r)return a-r+l;
        return a;
    }
    bool feq(ld a,ld b){
        return fabs(a-b)<_0;
    }
    bool chk(ld x){
        while(x>pi*2-_0)x-=pi*2;
        while(x<_0-pi*2)x+=pi*2;
        return std::fabs(x)<_0;
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++)scanf("%d%d",&ps[i].x,&ps[i].y);
        for(int i=0;i<n;i++){
            xs+=ps[i].x;
            ys+=ps[i].y;
        }
        for(int i=0;i<n;i++){
            (ps[i].x*=n)-=xs;
            (ps[i].y*=n)-=ys;
            ps[i].d=1ll*ps[i].x*ps[i].x+1ll*ps[i].y*ps[i].y;
            ps[i].a=atan2(ps[i].y,ps[i].x);
        }
        std::sort(ps,ps+n);
        int p0=0,p1;
        while(ps[p0].x==0&&ps[p0].y==0)++p0;
        for(p1=p0;p0<n;p0=p1){
            while(p1<n&&ps[p1].d==ps[p0].d)++p1;
            lp=0;
            for(int p2=p0;p2<p1;p2++){
                bool ab=1;
                ld m=ps[p2].a*2;
                for(int l=fix(p2-1,p0,p1),r=fix(p2+1,p0,p1);;l=fix(l-1,p0,p1),r=fix(r+1,p0,p1)){
                    if(!chk(ps[l].a+ps[r].a-m)){
                        ab=0;
                        break;
                    }
                    if(l==r)break;
                }
                if(ab==1)ls[lp++]=ps[p2].a;
                if(p1-p0&1)continue;
                ab=1;
                m=(ps[p2].a+ps[fix(p2+1,p0,p1)].a);
                for(int l=fix(p2,p0,p1),r=fix(p2+1,p0,p1),t=p1-p0>>1;t;--t,l=fix(l-1,p0,p1),r=fix(r+1,p0,p1)){
                    if(!chk(ps[l].a+ps[r].a-m)){
                        ab=0;
                        break;
                    }
                    if(l==r)break;
                }
                if(ab)ls[lp++]=m/2.;
            }
            for(int i=0;i<lp;i++){
                ld x=ls[i];
                while(x<-_0)x+=pi;
                while(x>pi-_0)x-=pi;
                ls[i]=x;
            }
            std::sort(ls,ls+lp);
            lp=std::unique(ls,ls+lp,feq)-ls;
            if(ad){
                int lp1=0,ap1=0;
                for(int i=0;i<ap;i++){
                    while(lp1<lp&&ls[lp1]<as[i]-_0)++lp1;
                    if(lp1==lp)break;
                    if(feq(as[i],ls[lp1]))as[ap1++]=as[i];
                }
                ap=ap1;
            }else{
                ad=1;
                for(int i=0;i<lp;i++)as[ap++]=ls[i];
            }
        }
        printf("%d",ap);
        return 0;
    }
  • 相关阅读:
    Android 百度地图 SDK v3.0.0 (三) 添加覆盖物Marker与InfoWindow的使用
    玩转Web之html+CSS(一)---论坛首页表格的实现
    Android 百度地图 SDK v3.0.0 (二) 定位与结合方向传感器
    Android 百度地图 SDK v3.0.0 (一)
    RabbitMQ (五)主题(Topic)
    RabbitMQ (四) 路由选择 (Routing)
    数据结构中的排序算法
    冒泡排序
    hashMap与hashTable的区别
    Java重载与重写的区别
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5745225.html
Copyright © 2011-2022 走看看