思路:一个二维坐标系中给出n个点,可以两两连线,问这些所有线段中能组成多少平行四边形。n <= 1000。
这里显然不能枚举组合,那样是n^4的做法,必然是超时的。那么我们可以用平四边形的等价定义,两条相互平分的线段的四个点是平行四边形的顶点,那么我们可以先用n^2de方法求出任意两个点的连线(某四边形的duijiaoxian)的中点。这样就有n*(n-1)/2个中点。然后我们sort一下,求出相同的点的个数,然后一这个点某平行四边形对角线的中点的四边形个数为x(x-1)/2。这样整体的时间复杂度是n^2*log(n)(排序)。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define CLR(x) memset(x, 0,sizeof x) #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; struct Point{ double x, y; Point(){} Point(double _x, double _y){ x = _x; y = _y; } bool operator < (const Point& rhs)const{ return x < rhs.x || (x == rhs.x && y < rhs.y); } Point operator + (const Point& rhs)const{ return Point(x + rhs.x, y + rhs.y); } Point operator - (const Point& rhs)const{ return Point(x - rhs.x, y - rhs.y); } double operator ^ (const Point& rhs)const{ return (x * rhs.y - y * rhs.x); } double operator * (const Point& rhs)const{ return (x * rhs.x + y * rhs.y); } Point operator * (const double Num)const{ return Point(x * Num,y * Num); } friend ostream& operator << (ostream& output,const Point& rhs){ output << "(" << rhs.x << "," << rhs.y << ")"; return output; } }; typedef Point Vector; /*向量的模*/ inline double Length(const Vector& A){//Get the length of vector A; return sqrt(A * A);//sqrt(x*x+y*y); } /*向量夹角*/ inline double Angle(const Vector& A,const Point& B){ return acos(A * B/Length(A)/Length(B)); } /*向量A旋转rad弧度*/ inline Point Rotate(const Vector& A, double rad){ return Vector(A.x*cos(rad) - A.y*sin(rad),A.x*sin(rad) + A.y*cos(rad)); } Point p[1010],ans[1000*500]; int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int t, icase = 0, n; cin >> t; while(t--){ cin >> n; for (int i = 0;i < n;++i) cin >> p[i].x >> p[i].y; LL sum = 0; int k = 0; for (int i = 0;i < n;++i){ for (int j = i + 1;j < n;++j){ ans[k].x = p[i].x + p[j].x;// ans[k].x /= 2; ans[k].y = p[i].y + p[j].y;// ans[k].x /= 2; k++; } } sort(ans,ans + k); int j; for (int i = 0;i < k;++i){ for (j = i + 1;j < k;++j){ if (ans[i].x != ans[j].x || ans[i].y != ans[j].y) break; } n = j - i; sum += 1LL*(n*(n - 1)) / 2; i = j - 1; } printf("Case %d: %lld\n", ++icase, sum); } return 0; }