2805:正方形

来源:互联网 发布:中山大学就业 知乎 编辑:程序博客网 时间:2024/05/16 00:39

2805:正方形

总时间限制: 8000ms 单个测试点时间限制: 4000ms 内存限制: 65536kB
描述
给出平面上一些点的坐标,统计由这些点可以组成多少个正方形。注意:正方形的边不一定平行于坐标轴。
输入
输入包括多组测试数据。每组的第一行是一个整数n (1 <= n <= 1000),表示平面上点的数目,接下来n行,每行包括两个整数,分别给出一个点在平面上的x坐标和y坐标。输入保证:平面上点的位置是两两不同的,而且坐标的绝对值都不大于20000。最后一组输入数据中n = 0,这组数据表示输入的结束,不用进行处理。
输出
对每组输入数据,输出一行,表示这些点能够组成的正方形的数目。
样例输入
4
1 0
0 1
1 1
0 0
9
0 0
1 0
2 0
0 2
1 2
2 2
0 1
1 1
2 1
4
-2 5
3 7
0 0
5 2
0
样例输出
1
6
1

注意:

map里面的key是结构体的时候要记得在结构体里面写上<的方法

#include <iostream>#include<map># include <stdio.h># include <string.h>#include<algorithm> using namespace std;//http://bailian.openjudge.cn/practice/2805///基本步骤就是先给点排序(map里面自动排序) ,然后对枚举两个点,对剩下两个点进行搜索即可 struct zb{    int x,y;    friend bool operator < (zb a, zb b) {        return a.x < b.x || (a.x == b.x && a.y < b.y);    }};int n,res;zb z[1100],z1,z2;map<zb,int> mp;//map里面是struct时要有<这个排序方法 bool f(zb a,zb b){    if(a.x!=b.x||a.y!=b.y){        return true;    }    return false;}int main(int argc, char *argv[]) {    while(cin>>n){        if(n==0)break;        res=0;        mp.clear();//每次都要重新初始化         for(int i=0;i<n;i++){            cin>>z[i].x>>z[i].y;            mp[z[i]]++;//hash每个点对应出现的次数             //加入map后会自动从小到大排序         }        for(int i=0;i<n;i++){            for(int j=0;j<n;j++){                if(i==j||!f(z[i],z[j]))continue;                //找对应两个点是否存在                 int dx=z[i].x-z[j].x;                int dy=z[j].y-z[i].y;                z1.x=z[j].x+dy;                z1.y=z[j].y+dx;                z2.x=z[i].x+dy;                z2.y=z[i].y+dx;                if(f(z1,z[i])&&f(z1,z[j])&&f(z2,z[i])&&f(z2,z[j])){                    if(mp.find(z1)!=mp.end()&&mp.find(z2)!=mp.end()){                        //cout<<mp[z1]<<" "<<mp[z2]<<endl;                        res=res+1*mp[z1]*mp[z2];                    }                }             }        }         cout<<res/4<<endl;    }    return 0;}