思想:1、可以枚举一个点为圆心,再枚举另一个点来连接这个点组成半径,长为d,即为该点到圆心的距离。
2、用map来记录一下有多少个点在这个圆上,即有多少个“”等腰三角形“”,先计算答案后再更新map
通过计算对称点来在set里面找题目给的是否有这个计算的对称点,有的话说明三点共线。
并且这一条线会被记录两次,分别是除去中心点 剩余的点被枚举到时候记录的、所有在答案我们要去掉cnt/2
学习:
map<int,int> mp
第一个是关键字,第二个是记录关键字的个数,二者一一映射,并且map是排好序的
代码:
#include <iostream>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#define int long long
using namespace std;
const int N = 2020;
int x[N],y[N];
int n,ans;
int dis(int i,int j)
{
return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
signed main()
{
cin >> n;
set<pair<int,int>> s;
for(int i=1;i<=n;i++){
cin >> x[i] >> y[i];
s.insert({x[i],y[i]});
}
map<int,int> mp;
for(int i=1;i<=n;i++){
int cnt=0;
for(int j=1;j<=n;j++){
if(i!=j){
int d=dis(i,j);
ans+=mp[d];
mp[d]++;
int xx=2*x[i]-x[j];
int yy=2*y[i]-y[j];
//用set集合,记录题目给的坐标点 是否有我们计算出来的对称的点
//有:说明此时三个点共线,记录一下,再最后减去
if(s.count({xx,yy}))cnt++;
}
}
ans-=cnt/2;
mp.clear();
}
cout << ans;
}