题目大意
平面上有n个点,问你这n个点能组成多少个四条边都是平行于x轴或y轴的矩形。
思路
对这n个点排序,x小的在前,x相同的时候y小的在前。
然后对于所有xi相同的点,用map记录可能存在的边<yi, yj>的个数,很明显,xi相同的情况下,<yi, yj>是平行于y轴的,如果边<yi, yj> 的个数为m,那么能组成的矩形的个数为C
(
2
m
)
\binom{2}{m}
(m2),也可以直接理解成m - 1 + m - 2 + … 3 + 2 + 1,即第一条边可以与其后面的m - 1条边组成矩形,第二条边可以与其后面的m - 2条边组成矩形,以此类推,这个方法就是O(n)的了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
unordered_map<pair<int,int>, int>mp;
struct node
{
int x, y;
bool operator < (node j)
{
if(x == j.x)
{
return y < j.y;
}
return x < j.x;
}
}p[2005];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d%d", &p[i].x, &p[i].y);
}
sort(p, p + n);
int ans = 0;
for(int i = 0; i < n; i++)
{
int pos = i + 1; // 找与p[i].x相同的点
while(pos < n && p[pos].x == p[i].x)
{
pos++;
}
for(int j = i; j < pos; j++)
{
for(int k = j + 1; k < pos; k++)
{
int y1 = p[j].y;
int y2 = p[k].y;
ans += mp[make_pair(y1, y2)];
mp[make_pair(y1, y2)]++;
}
}
i = pos - 1;
}
printf("%d\n", ans);
return 0;
}