zoukankan      html  css  js  c++  java
  • PKU 2002 Squares(二维点哈希+平方求余法+链地址法)

    题目大意:原题链接

    给定平面上的N个点,求出这些点一共可以构成多少个正方形。

    解题思路:

    若正方形为ABCD,A坐标为(x1, y1),B坐标为(x2, y2),则很容易可以推出C和D的坐标。对于特定的A和B坐标,C和D可以在线段AB的上面或者下面,即有两种情况。

                根据构造三角形全等可以得知(很简单,注意下细节,不要把坐标弄混就行)

    CD在AB上面x3=x2+(y1-y2),y3=y2+(x2-x1);    x4=x1+(y1-y2),y4=y1+(x2-x1);

    CD在AB下面x3=x2-(y1-y2),y3=y2-(x2-x1);      x4=x1-(y1-y2),y4=y1-(x2-x1);

    因此只需要枚举点A和点B,然后计算出两种对应的C和D的坐标,判断是否存在即可。这样计算完之后得到的答案是正确答案的4倍,因为正方形的4条边都枚举了,所以答案要右移两位

    Insert(int x,int y)采用平方求余法构造哈希函数,链地址法(用类邻接表法实现)处理冲突进行哈希

    Judge(int x,int y)通过查找判断CD两点是否同时存在,即能判断是否可以构成正方形

    #include<iostream>  
    #include<cstring>  
    #include<algorithm>  
    using namespace std;  
    const int maxn=1010;  
    const int N=10007;  
    int px[maxn],py[maxn];  
    struct Node  
    {  
        int x,y;  
        int next;  
    }node[N];
    long long ans;  
    int n,cur,Hash[N]; 
    
    void Insert(int x,int y)  
    {  
        int h=(x*x+y*y)%N;  
        node[cur].x=x;  
        node[cur].y=y;  
        node[cur].next=Hash[h];  
        Hash[h]=cur++;  
    }  
    bool Judge(int x,int y)  
    {  
        int h=(x*x+y*y)%N;    
        int next=Hash[h];  
        while(next!=-1){  
            if(x==node[next].x&&y==node[next].y) 
                return true;  
            next=node[next].next;  
        }  
        return false;  
    }  
      
    int main()  
    {  
        while(cin>>n,n){  
            memset(Hash,-1,sizeof(Hash));
            cur=0,ans=0;  
            for(int i=0;i<n;i++){  
                cin>>px[i]>>py[i];
                Insert(px[i],py[i]);  
            }  
            for(int i=0;i<n;i++){//先枚举考虑CD在AB上面  
                for(int j=i+1;j<n;j++){  
                    int x3=px[j]+(py[i]-py[j]);  
                    int y3=py[j]+(px[j]-px[i]);  
                    int x4=px[i]+(py[i]-py[j]);  
                    int y4=py[i]+(px[j]-px[i]);  
                    if(Judge(x3,y3)&&Judge(x4,y4)) ans++;  
                }
            }  
            for(int i=0;i<n;i++){//再枚举考虑CD在AB下面  
                for(int j=i+1;j<n;j++){  
                    int x3=px[j]-(py[i]-py[j]);  
                    int y3=py[j]-(px[j]-px[i]);  
                    int x4=px[i]-(py[i]-py[j]);  
                    int y4=py[i]-(px[j]-px[i]);  
                    if(Judge(x3,y3)&&Judge(x4,y4)) ans++;  
                }//要判断C点和D点同时存在才能构成正方形   
            }  
            ans>>=2;  
            printf("%lld
    ",ans);  
        }  
    }  
  • 相关阅读:
    篝火晚会
    SECHS
    emmc4.X boot1 and boot2
    imx6Q Android7.1 Udisk Mount
    imx6Q 4.1.15 Perf support
    imx6Q 4.1.15 Kgtp support
    imx6Q 4.1.15 early console support
    imx6Q USB OTG Host/Device纯软件切换
    iMX6Q DDR Stresstest
    iMX6Q PowerSave调试
  • 原文地址:https://www.cnblogs.com/freinds/p/6415264.html
Copyright © 2011-2022 走看看