題目連接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; }