1. 数三角-枚举-STL

0数三角 - 蓝桥云课 (lanqiao.cn)

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
//res是有多少种选法
int n,res;
//存当前坐标的点有多少个
map<pair<int,int>,int> geshu;
void solve(){
	cin>>n;
	//动态数组,每一行又是一个有两个元素的数组,用来存每个点的坐标
	vector<array<int,2>> a(n);
	for(int i=0;i<n;i++){
		cin>>a[i][0]>>a[i][1];
		geshu[{a[i][0],a[i][1]}]++;
	}
	//a[i]是顶点
	for(int i=0;i<n;i++){
		//存 到当前顶点,距离为d的点的集合,相当于位于同一个圆上
		//键是半径,值是相同半径的点的集合
		map<int,vector<int>> b;
		for(int j=0;j<n;j++){
			//d是半径(a[j]点到顶点的距离)
			//这里不用开平方,因为开平方会有小数,会有精度的问题,所以不用开方了,反正答案一样
			int d=(a[i][0]-a[j][0])*(a[i][0]-a[j][0])+(a[i][1]-a[j][1])*(a[i][1]-a[j][1]);
			b[d].push_back(j);
		}
		//遍历不同的半径(不同的圆)
		for(auto t:b){
			//map的键用b.first,值用b.second
			vector<int> b=t.second;
			//相同圆上的点的数量
			int cnt=b.size();
			//用高中学过的排列组合中的组合数公式,CM2,即从m个里面选2个
			res+=cnt*(cnt-1)/2;
			//del是三点共线的情况,组不成三角形,要去掉
			int del=0;
			//遍历此半径上的不同点
			for(int j=0;j<cnt;j++){
				//顶点的坐标
				int x1=a[i][0],y1=a[i][1];
				//当前点的坐标
				int x2=a[b[j]][0],y2=a[b[j]][1];
				//会和当前点和顶点在同一条线上的坐标
				int x=2*x1-x2,y=2*y1-y2;
				del+=geshu[{x,y}];
			}
			//因为一个点和另一个点在一条线上,那么这个点和另一个点判断时会各判断共线一次
			//会重复,所以得除以二
			//去掉共线的情况
			res-=del/2;
		}
	}
	cout<<res;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值