LightOJ
来源:互联网 发布:2015家电市场销售数据 编辑:程序博客网 时间:2024/06/05 02:03
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
Input starts with an integer T (≤ 15), denoting the number of test cases.
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
For each case, print the case number and the number of parallelograms that can be formed.
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
Case 1: 5
Case 2: 6
题意:给你n个点,任选四个点为一组,问能找到多少组能构成平行四边形的点,点可以重复使用。数据保证任意四点不共线,n的范围是1000.点的坐标范围是1e9;
思路:用题目给的判断两直线平行肯定是要超时的。
还有一个判定平行四边形的方法就是
如果两条线段的中点重合,那么这两条线段的端点可以组成一个平行四边形。 (初中知识……)
代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<string>#include<cmath>#include<iostream>using namespace std;#define ll long longconst ll Max=1e6+9;struct nod{ double x; double y;}a[1009],noe[Max];//a数组存题目给的点的坐标。//noe数组存任意两点构成的线段的中点的坐标bool cmp(nod a,nod b){ if(a.x<b.x) return 1; else if(a.x==b.x&&a.y<b.y) return 1; return 0;}int main(){ int t; scanf("%d",&t); int k=0; while(t--) { k++; int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&a[i].x,&a[i].y); } int pos=1; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { noe[pos].x=(a[i].x+a[j].x)/2; noe[pos++].y=(a[i].y+a[j].y)/2; } } sort(noe+1,noe+pos,cmp);//排序后一遍遍历就可以找到所有的相同的中点坐标 //for(int i=1;i<pos;i++) // cout<<noe[i].x<<" "<<noe[i].y<<endl; ll num=1;//记录当前相同的中点坐标的个数 ll ans=0;//记录最终结果 for(int i=2;i<pos;i++) { if(noe[i].x==noe[i-1].x&&noe[i].y==noe[i-1].y) { num++; } else { ans+=(num)*(num-1)/2;//当前有num个相同的中点坐标,那么答案就加上C(num,2)个,组合数。 num=1;//num要记得重置 } } if(num>1)//遍历完还要判断一下num的值 ans+=(num)*(num-1)/2; printf("Case %d: %lld\n",k,ans); } return 0;}