zoukankan      html  css  js  c++  java
  • POJ 2002 统计正方形 HASH

    题目链接:http://poj.org/problem?id=2002

    题意:给定n个点,问有多少种方法可以组成正方形。

    思路:我们可以根据两个点求出对应正方形[有2个一个在两点左边,一个在两点右边]另外两个点的左边。例如

    已知:(x1,y1) (x2,y2)
    则x3=x1+(y1-y2) y3= y1-(x1-x2) x4=x2+(y1-y2) y4= y2-(x1-x2)
    或x3=x1-(y1-y2) y3= y1+(x1-x2) x4=x2-(y1-y2) y4= y2+(x1-x2)

    枚举两个点,进行HASH,然后再枚举两个点然后求另外两个点,再从HASH表找,冲突用拉链法。

    这种做法会使同一个正方形按照不同的顺序被枚举了四次,因此最后的结果要除以4.

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cmath>
    #include<set>
    using namespace std;
    typedef long long int LL;
    typedef unsigned int uint;
    const int MAXN=1000+5;
    const int MOD=99991;
    struct Point{
        int x,y;
        Point(int a=0,int b=0):x(a),y(b){};
    };
    Point P[MAXN];
    vector<Point>Hash[MOD];
    void Init(){
        for(int i=0;i<MOD;i++){
            Hash[i].clear();
        }
    }
    void InsetHash(Point a){
        int Num=(a.x*a.x+a.y*a.y)%MOD;
        Hash[Num].push_back(a);
    }
    bool Search(Point a){
        int Num=(a.x*a.x+a.y*a.y)%MOD;
        for(int i=0;i<Hash[Num].size();i++){
            if(a.x==Hash[Num][i].x&&a.y==Hash[Num][i].y){
                return true;
            }
        }
        return false;
    }
    int main(){
    #ifdef kirito
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
        int n;
        while(scanf("%d",&n)&&n){
            int ans=0; Init();
            for(int i=0;i<n;i++){
                scanf("%d %d",&P[i].x,&P[i].y);
            }
            for(int i=0;i<n;i++){
                InsetHash(P[i]);
            }
            for(int i=0;i<n;i++){
                for(int j=i+1;j<n;j++){
                    Point C,D;
                    C.x=P[i].x+(P[i].y-P[j].y); C.y=P[i].y-(P[i].x-P[j].x);
                    D.x=P[j].x+(P[i].y-P[j].y); D.y=P[j].y-(P[i].x-P[j].x);
                    if(Search(C)&&Search(D)){
                        ans++;
                    }
                    C.x=P[i].x-(P[i].y-P[j].y); C.y=P[i].y+(P[i].x-P[j].x);
                    D.x=P[j].x-(P[i].y-P[j].y); D.y=P[j].y+(P[i].x-P[j].x);
                    if(Search(C)&&Search(D)){
                        ans++;
                    }
                }
            }
            printf("%d
    ",ans>>2);
        }
        return 0;
    }
  • 相关阅读:
    分享memcache和memcached安装过程(转)
    ios画图总结
    mac os下通过命令行的方式编译c++代码并在xcode里引用
    ubuntu访问windows共享文件夹
    为iphone 及iphone simulator编译boost库
    ubuntu 11.10 x64 安装oracle 11gR2时碰到的问题及解决方法
    模拟器与真机下ffmpeg的编译方法(总结版)
    ios 在View里绘图
    memcached1.4.4在ubuntu下编译的注意事项
    Google Code 服务试用
  • 原文地址:https://www.cnblogs.com/kirito520/p/5645712.html
Copyright © 2011-2022 走看看