问题描述
小明在二维坐标系中放置了 n 个点,他想从中选出一个包含三个点的子集,使得这三个点能够组成一个三角形。
由于这样的方案太多了,他决定只选择那些可以组成等腰三角形的方案。
请帮他计算出一共有多少种选法可以组成等腰三角形。
输入格式
共 n + 1 行:
- 第 1 行:一个正整数 
n,表示点的数量。 - 接下来的 
n行:每行两个整数xᵢ、yᵢ,表示第i个点的坐标。 
输出格式
输出 1 行,一个整数,表示可以组成等腰三角形的选法数量。
样例输入
5
1 1
4 1
1 0
2 1
1 2
 
样例输出
4
 
样例说明
一共有 4 种选法可以组成等腰三角形:
{3, 4, 5}{1, 3, 4}{5, 2, 3}{1, 4, 5}
评测用例规模与约定
- 对于 20% 的数据,保证 
n ≤ 200 - 对于 100% 的数据,保证: 
n ≤ 20000 ≤ xᵢ, yᵢ ≤ 10⁹
 
c++代码
#include<bits/stdc++.h>
#include<math.h>using namespace std;typedef long long ll;ll n, ans = 0;
vector<vector<ll>> arr;
unordered_map<ll, vector<ll>> mp;ll delta(ll x1, ll y1, ll x2, ll y2) {return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}int main() {scanf("%lld", &n);arr = vector<vector<ll>>(n, vector<ll>(2));for (ll i = 0; i < n; i++) {scanf("%lld %lld", &arr[i][0], &arr[i][1]);}for (ll i = 0; i < n; i++) {mp.clear();for (ll j = 0; j < n; j++) {if (j == i) continue;ll d = delta(arr[i][0], arr[i][1], arr[j][0], arr[j][1]);vector<ll> mid = mp[d];for (ll k = 0; k < mid.size(); k++) {if (4 * d > delta(arr[j][0], arr[j][1], arr[mid[k]][0], arr[mid[k]][1])) ans++;}mp[d].push_back(j);}}printf("%lld", ans);return 0;
}//by wqs
 
这个题目需要注意三点共线的情况,要把这种情况舍去