1 条题解

  • 0
    @ 2025-4-21 22:10:44

    题意分析

    题目要求我们计算平面上给定点的集合中可以形成多少个平行四边形。平行四边形的定义是:有四个点 A,B,C,DA,B,C,D,使得线段 ABAB 平行且等于线段 CDCD,同时线段 BCBC 平行且等于线段 ADAD输入说明 输入的第一行包含一个整数 t,表示测试用例的数量。一个整数 n,表示点的数量。 接下来的 n 行,每行包含两个整数 x,y,表示一个点的坐标。 输出说明 对于每个测试用例,输出一个整数,表示可以形成的平行四边形的数量。

    解题思路

    1.点的表示: 使用结构体表示一个点,包含两个整数 x 和 y。

    2.中点计算: 对于每对点 AABB,计算它们的中点(实际上是计算向量(A+B) (A+B) 的和),因为如果 A,B,C,DA,B,C,D构成平行四边形,那么 (A+B)(A+B)=(C+D)(C+D)

    3.枚举所有点对: 枚举所有可能的点对 (i,j)(i,j)i<j),计算每对点的和(中点向量),并存储这些和。

    4.排序和计数: 将所有计算出的向量和进行排序。 遍历排序后的向量和,统计出现次数相同的向量和,这些相同的向量和表示可以形成多个平行四边形的对。

    5.计算平行四边形数量: 对于每个出现次数 k 大于 1 的向量和,可以形成 k(k1)2\frac{k(k-1)}{2}个平行四边形。

    代码实现

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include <cstring>
    using namespace std;
    struct lkq
    {
    	int x;
    	int y;
    }p[1005];
    struct lkq s[1005*1005];
    struct lkq mind(struct lkq a,struct lkq b)
    {
    	struct lkq mind;
    	mind.x=(a.x+b.x);
    	mind.y=(a.y+b.y);
    	return mind;
    }
    bool cmp(struct lkq a,struct lkq b)
    {
    	if(a.x==b.x)
    		return a.y<b.y;
    	return a.x<b.x;
    }
    int main()
    {
    	int T,n;
    	cin>>T;
    	while(T--)
    	{
    		int c=0,ans=1;
    		scanf("%d",&n);
    		for(int i=0;i<n;i++)
    			scanf("%d%d",&p[i].x,&p[i].y);
    		for(int i=0;i<n-1;i++)
    		{
    			for(int j=i+1;j<n;j++)
    			{
    				s[c++]=mind(p[i],p[j]);
    			}
    		}
    		sort(s,s+c,cmp);
    		int sum=0;
    		for(int i=0;i<c-1;i++)
    		{
    			if(s[i].x==s[i+1].x&&s[i].y==s[i+1].y)
    				ans++;
    			else
    			{
    				sum+=(ans-1)*ans/2;
    				ans=1;
    			}
    		}
    		printf("%d\n",sum);
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    972
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者