zoukankan      html  css  js  c++  java
  • poj1971:Parallelogram Counting

    Description

    There are n distinct points in the plane, given by their integer coordinates. Find the number of parallelograms whose vertices lie on these points. In other words, find the number of 4-element subsets of these points that can be written as {A, B, C, D} such that AB || CD, and BC || AD. No four points are in a straight line.

    Input

    The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases. It is followed by the input data for each test case. 
    The first line of each test case contains an integer n (1 <= n <= 1000). Each of the next n lines, contains 2 space-separated integers x and y (the coordinates of a point) with magnitude (absolute value) of no more than 1000000000. 

    Output

    Output should contain t lines. 
    Line i contains an integer showing the number of the parallelograms as described above for test case i. 

    Sample Input

    2
    6
    0 0
    2 0
    4 0
    1 1
    3 1
    5 1
    7
    -2 -1
    8 9
    5 7
    1 1
    4 8
    2 0
    9 8
    

    Sample Output

    5
    

    6

    在二维坐标上给出n个点 找出四个点组成一个平行四边形 问你能够组成几个平行四边形

    我们知道四边形对角线相较于中点 而中点的横纵坐标就等于对角线两点横纵坐标和的一半 这样我们只要找出中点相同的边的数量

    然后两两组合即可

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    struct node
    {
    	int x,y;
    }dian[10001];
    node mid[500001];
    bool 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;
    	scanf("%d",&t);
    	while(t--)
    	{
    		int n;
    		scanf("%d",&n);
    		for(int i=0;i<n;i++)
    		{
    		 scanf("%d%d",&dian[i].x ,&dian[i].y );
    		}
    		int cut=0;
          for(int i=0;i<n;i++)
          {
          	for(int j=i+1;j<n;j++)//把给出的点两两组合连成边 
          	{
          		 mid[cut].x =dian[i].x +dian[j].x ;//这里没有除以2是为了避免出现小数 结果是不变的 
          		 mid[cut].y =dian[i].y+dian[j].y ;
          		 cut++;
    		  }
    	  }
    	  sort(mid,mid+cut,cmp); //排序 让中点坐标相同的排列在一起 
    	  int ans=0;
    	  int flog=0;//起点边的坐标 
    	  int sum=1;//每次在新区间开始的时候中点数为1(起点边的中点)   s 
    	  for(int i=1;i<cut;i++)
    	  {
    	     if(mid[flog].x ==mid[i].x&&mid[flog].y==mid[i].y )
    		 {
    		 	sum++;
    			 }	
    			 else
    			 {
    			 	ans=ans+sum*(sum-1)/2;//找出的边两两组合 
    			 	sum=1;//初始化
    			 	flog=i;//更新新的起点 
    			 }
    	  }
    	  printf("%d
    ",ans);
    	}
    	return 0;
     } 


  • 相关阅读:
    Java版AES-CBC-CMAC加密
    并发编程(十九):并发编程实践
    并发编程(十八):ScheduledThreadPoolExcutor和FutureTask
    并发编程(十七):Excutor与ThreadPoolExcutor
    并发编程(十六):线程池概述
    并发编程(十五):Java并发工具类
    并发编程(十四):原子操作类
    并发编程(十三):Fork-Join框架
    并发编程(十二):阻塞队列
    并发编程(十一):非阻塞队列ConcurrentLinkedQueue
  • 原文地址:https://www.cnblogs.com/kingjordan/p/12027048.html
Copyright © 2011-2022 走看看