给你1000个点,判断这些点最多能组成多少个正方形。
以前没仔细想就放过去了(题意记下来了。。。)。回顾不会做的题的时候看到了,想了下,想了个N^2LOGN的算法。准确的是n^2/2*logn,可以承受,就写了下。
就是枚举对角线,然后判断另一条对角线的俩点存在不。查找用二分查找。手写的二分查找有问题- - 。。。原来我的二分一直都有问题啊 = = 。。今天才发现。改了下 - - 悲剧。
zoj上基本是险过,交了多次才擦边过一次。。。其他都是TLE,poj的话还好,都过了。
后来看poj的discuss,发现我枚举对角线有点多余,枚举边长就可以了,少一次计算等于,呵呵,改成枚举边长了,旋转的时候要旋转90度和270度了,zoj不再TLE了 = =。。
貌似查找还可以用hash,可惜我不会哎。用c++的binary_search一直不知道那个比较函数怎么写,看了人家的,原来比较函数就是和排序的一样啊,郁闷。改了改,结果zoj时间提升了,poj过不去了,一直TLE,神呐。。。
贴的是我手写的二分。。。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <string> #include <algorithm> using namespace std; const int MAX = 1010; struct point { double x,y;}; point p[MAX]; const double eps = 1e-6; bool dy(double x,double y) { return x > y + eps;} // x > y bool xy(double x,double y) { return x < y - eps;} // x < y bool dyd(double x,double y) { return x > y - eps;} // x >= y bool xyd(double x,double y) { return x < y + eps;} // x <= y bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y bool bsearch(point a,int n) { int begin = 0,end = n-1; while( begin <= end ) { int mid = ( begin + end )/2; if( dd(a.x,p[mid].x) && dd(a.y,p[mid].y) ) return true; if( dy(a.x,p[mid].x) || dd(a.x,p[mid].x) && dy(a.y,p[mid].y) ) begin = mid + 1; else end = mid - 1; } return false; } point Whirl(double cosl, double sinl, point a, point b) { b.x -= a.x; b.y -= a.y; point c; c.x = b.x * cosl - b.y * sinl + a.x; c.y = b.x * sinl + b.y * cosl + a.y; return c; } bool check(point a,point b,int n) { point t = Whirl(0.0,1.0,a,b); if( !bsearch(t,n) ) return false; t = Whirl(0.0,-1.0,b,a); if( !bsearch(t,n) ) return false; return true; } int solve(point p[],int n) { int sum = 0; for(int i=0; i<n; i++) for(int k=i+1; k<n; k++) if( i != k && check(p[i],p[k],n) ) sum++; return sum; } bool cmp(point a,point b) { if( dd(a.x,b.x) ) return xy(a.y,b.y); return xy(a.x,b.x); } int main() { int ncases,n; scanf("%d",&ncases); while( ncases-- ) { while( scanf("%d",&n) && n ) { for(int i=0; i<n; i++) scanf("%lf%lf",&p[i].x,&p[i].y); sort(p,p+n,cmp); int ans = solve(p,n); printf("%d\n",ans/2); } if( ncases ) printf("\n"); } return 0; }