题目链接:
传送门

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 1010;
const int M = 1000010;

ll t, ca, n;

struct Node {
	int x, y;
} dot[N], m[M];

//排序函数
bool cmp(Node a, Node b) {
	if(a.x == b.x)
		return  a.y < b.y;
	return a.x < b.x;
}

int main() {
	scanf("%lld", &t);
	while(t--) {
		scanf("%lld", &n);
		ll idx = 0, ans = 0;
		for(ll i = 0; i < n; i++)
			scanf("%lld%lld", &dot[i].x, &dot[i].y);
		//计算出所有点的中点,此处没有除以2,以防精度问题
		for(ll i = 0; i < n; i++) {
			for(int j = i + 1; j < n; j++) {
				m[idx].x = dot[i].x + dot[j].x;
				m[idx++].y = dot[i].y + dot[j].y;
			}
		}
		sort(m, m + idx, cmp);
		ll cnt = 1;
		//统计相同中点的个数,然后把这个数进行排列组合并加入答案中。
		for(ll i = 1; i < idx; i++) {
			if(m[i].x == m[i - 1].x && m[i].y == m[i - 1].y)
				cnt++;
			else {
				ans += cnt * (cnt - 1) / 2;
				cnt = 1;
			}
		}
		printf("Case %lld: %lld\n", ++ca, ans);
	}
}

这道题就是求能组成多少个平行四边形,根据平行四边形的性质,我们可以知道平行四边形的对角线互相平分,即两对对角的中点是相等的。由此性质我们可以计算出所有点与点之间的中点,如果两个中点相等那么就可以构成一个平行四边形。而计算是我们可以计算中点为当前点的个数,然后经行组合从总数中选两个,看能组成的方案数,然后加入答案中。

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐