View Code of Problem 1056

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; 
struct node{
	int x,y;
}dian[1010],mid[1010*1010];

int cmp(node a,node b)
{
	if(a.x!=b.x)
		return a.x<b.x;
	else
		return a.y<b.y;
}
int main()
{
	int t,n,cont=0;
	scanf("%d",&t);
	while(t--)
	{	
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d%d",&dian[i].x,&dian[i].y);
		}
		int o=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				mid[o].x=dian[i].x+dian[j].x;//两点连线的中点横坐标(为了简便没除以2) 
				mid[o].y=dian[i].y+dian[j].y;
				o++;
			}
		}
		sort(mid,mid+o,cmp); //记得排序。。。 
		int next=0,ans=0;
		int sum=1;//一条边就有一个中点,所以sum最少为1; 
		for(int i=1;i<o;i++)
		{
			if(mid[i].x==mid[next].x&&mid[i].y==mid[next].y){//两条边中点相同,sum就加一; 
				sum++;
			}
			else{
				next=i;
				ans=ans+sum*(sum-1)/2;	//根据找到的有相同中点的边的条数(有相同中点那么一定相交)计算能组成多少个平行四边形,自己举几个例子就能看出来为啥这样; 
				sum=1;	// 遇到中点不同说明又有“一簇”拥有相同中点的相交的边,需要另外开始算; 
			}
		}
		printf("%d\n",ans);//输出平行四边形个数 
	}
	return 0;
}

Double click to view unformatted code.


Back to problem 1056