点击打开题目
1058 - Parallelogram Counting PDF (English)StatisticsForum Time Limit: 2 second(s)Memory Limit: 32 MBThere 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 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.
For each case, print the case number and the number of parallelograms that can be formed.
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
Case 1: 5
Case 2: 6
差点wa到放弃比赛的题。刚开始思路是先选出所有平行的线,然后去掉三点共线的,然后除以2就得到结果,但是还是TLE了。
后来把线的向量全部放到一四象限(这一点出了小问题,查了俩小时),然后再计数的时候同时判断三点共线,这样就省时间了,最后终于查出来了。
代码如下:
#include <stdio.h> #include <cstring> #include <algorithm> using namespace std; #define CLR(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define LL long long struct node { int x,y; }dot[1011]; struct node2 { int a,b; int x,y; }edge[500500]; bool check(node2 a,node2 b) { if (a.a == b.a || a.a == b.b || a.b == b.a || a.b == b.b) return false; //三点共线 if ((dot[b.b].x - dot[a.a].x) * a.y == (dot[b.b].y - dot[a.a].y) * a.x) return false; return true; } bool cmp(node2 a,node2 b) { if (a.x == b.x) return a.y < b.y; return a.x < b.x; } int main() { int u; int n; int Case = 1; scanf ("%d",&u); while (u--) { scanf ("%d",&n); for (int i = 0 ; i < n ; i++) scanf ("%d %d",&dot[i].x,&dot[i].y); int ans = 0; int ant = 0; for (int i = 0 ; i < n ; i++) { for (int j = i + 1 ; j < n ; j++) { edge[ant].x = dot[i].x - dot[j].x; edge[ant].y = dot[i].y - dot[j].y; edge[ant].a = i; edge[ant].b = j; if (edge[ant].x <= 0 && edge[ant].y <= 0) { edge[ant].x = -edge[ant].x; edge[ant].y = -edge[ant].y; } if (edge[ant].x <= 0 && edge[ant].y >= 0) //这里y的值可能由第一个x的值改变 { edge[ant].x = -edge[ant].x; edge[ant].y = -edge[ant].y; } ant++; } } sort(edge , edge+ant , cmp); int st = 0; while (st < ant) { int i,j; for (i = st ; edge[i].x == edge[st].x && edge[i].y == edge[st].y ; i++) { for (j = i + 1 ; edge[j].x == edge[st].x && edge[j].y == edge[st].y ; j++) { if (check(edge[i],edge[j])) ans++; } } st = i; } ans >>= 1; printf ("Case %d: %d\n",Case++,ans); } return 0; }