题目连接html
题目描述node
平面上有 nn 个坐标相异的点,请问当中有多少组非共线的三个点,这三个点的 外心 也在这 nn 个点之中?ios
输入描述spa
第一行有一个正整数 nn 表明平面上的点数。code
接下来有 nn 行,当中的第 ii 行包含两个整数 x_i, y_i,xi,yi 表明第 i 个点的坐标是 (x_i, y_i)(xi,yi)。htm
1<=n<=2000blog
-10^9<=x,y<=10^9ci
若 i != j ,则(xi,yi)!=(xj,yj);get
样例输入string
5 0 0 -2 0 0 2 -1 1 2 0
样例输出
2
拿到这个题时,想着暴力,可是涉及到四个for,因此超时。比赛时就没搞出来,甚是遗憾。打完后看别人的AC代码,恍然大悟!
若是一个点到另外三个点的距离相等,那么这三个点确定不共线,因此这点压根不须要去管了,直接去找一个点a1到另外点的距离,用map记录距离出现次数,若是出现某个距离出现次数K>=3,那么a1是这些点的外心,因为要选组合数,那么进行C K 3就能够了,从出现次数中选择三个就是一组,因此C K 3。
另外还有map迭代器的写法,老是忘
#include<cstring> #include<iostream> #include<map> #include<algorithm> using namespace std; const int maxn = 2e3+10; typedef long long ll; ll num[maxn]; struct node { ll x,y; }st[maxn]; ll distance(ll x1,ll y1,ll x2, ll y2) { return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main() { int n ; cin>>n; for(int i = 0 ; i< n ; i++) { cin>>st[i].x>>st[i].y; } ll sum = 0 ; for(int i = 0 ; i <n ;i ++) { map<ll,ll>mm; for(int j = 0 ; j<n ; j++) { if(i!=j) { ll s=distance(st[i].x,st[i].y,st[j].x,st[j].y); // cout<<s<<endl; mm[s]++; } }
map<ll,ll>::iterator it; //遍历map写法
for(it = mm.begin();it!=mm.end();it++) { if(it->second>=3) { ll k = it->second; // cout<<k<<endl; sum+=k*(k-1)*(k-2)/6; //C k 3 } } } cout<<sum<<endl; return 0; }