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);  
        }  
    }  
  • 相关阅读:
    【LeetCode】Validate Binary Search Tree
    【LeetCode】Search in Rotated Sorted Array II(转)
    【LeetCode】Search in Rotated Sorted Array
    【LeetCode】Set Matrix Zeroes
    【LeetCode】Sqrt(x) (转载)
    【LeetCode】Integer to Roman
    贪心算法
    【LeetCode】Best Time to Buy and Sell Stock III
    【LeetCode】Best Time to Buy and Sell Stock II
    CentOS 6 上安装 pip、setuptools
  • 原文地址:https://www.cnblogs.com/freinds/p/6415264.html
Copyright © 2011-2022 走看看