问题描述
小明在二维坐标系中放置了 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 ≤ 2000
0 ≤ 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
这个题目需要注意三点共线的情况,要把这种情况舍去