题意
给出n个点, 输入保证没有重复点, 且不会有三点共线, 求这些点能够构成的平行四边形的个数
思路
最后B题还有半个来小时没考虑全瞎瘠薄写没过
赛后补B题发现人家全用向量做的
我居然用的长度和斜率跑了2000+ms真的是太傻逼了
大概就是用n*n跑一遍点, 枚举出所有可能组成的边(以向量形式存储), 若有两个向量完全相同则他们能构成一个平行四边形.
自己写的时候傻逼了, 用的线段长度+斜率模拟的
AC代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#define mst(a) memset(a, 0, sizeof a)
using namespace std;
const int maxn = 2000+5;
const int INF = 0x3f3f3f3f;
struct point{
int x, y;
}p[maxn];
double getk(int x, int y){
if( x == 0 ) return 1;
return (double)y/(double)x;
}
int getall(int n){
int sum = 0;
for( int i = 1; i < n; i++ )
sum += i;
//printf("%d %d\n",n , sum);
return sum;
}
struct lines{
double len;
double kk;
bool operator <( const struct lines& l ) const{
if( kk == l.kk )
return len < l.len;
return kk < l.kk;
}
};
map<lines, int> mp;
double getlen( int x1, int y1, int x2, int y2 ){
double xx = abs(x1-x2); xx = xx * xx;
double yy = abs(y1-y2); yy = yy * yy;
return sqrt(xx+yy);
}
int main()
{
int n;
scanf("%d",&n);
for( int i = 0; i < n; i++ )
scanf("%d%d", &p[i].x, &p[i].y);
int m = 0;
for( int i = 0; i < n; i++ ){
for( int j = i+1; j < n; j++ ){
int xx = p[i].x-p[j].x, yy = p[i].y-p[j].y;
double kkk = getk(xx, yy);
double l = getlen(p[i].x, p[i].y, p[j].x, p[j].y);
lines q;
q.kk = kkk, q.len = l;
mp[q]++;
}
}
int ans = 0;
map<lines, int>::iterator it = mp.begin();
for( ; it != mp.end(); it++ )
ans += getall(it->second);
printf("%d\n",ans/2);
return 0;
}