Aizu Online Judge 1132 Circle and Points

POJ にsubmitしてTLEしたコードを、そのままAOJに投げつけたら通りました(は?)
2点を全通り選んで、その2点を通る半径1の円を描き、それで囲める点の個数の最大値を調べる、という方針で(嘘解法かも知れない)

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
static const int MAX_N = 300;
 
#define EPS (1e-10)
 
class Point{
    public:
        double x, y;
 
        Point(double x = 0, double y = 0): x(x), y(y) {}
 
        Point operator + (Point p){ return Point(x + p.x, y + p.y);}
        Point operator - (Point p){ return Point(x - p.x, y - p.y);}
        Point operator * (double a){ return Point(a * x, a * y);}
        Point operator / (double a){ return Point(x / a, y / a);}
 
        double abs(){ return sqrt(norm());}
        double norm(){ return x * x + y * y;}
 
        bool operator < (const Point &p) const{
            return x != p.x ? x < p.x : y < p.y;
        }
 
        bool operator == (const Point &p) const{
            return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
        }
};
 
class Circle{
    public:
        Point c;
        double r;
        Circle(Point c = Point(), double r = 0.0): c(c), r(r) {}
};
 
typedef Point Vector;
 
int N;
Point p[MAX_N];
 
double arg(Vector p){return atan2(p.y, p.x);}
Vector polar(double a, double r){return Point(cos(r) * a, sin(r) * a);}
 
double getDistance(Point a, Point b){
    return (a - b).abs();
}
 
pair<Point, Point> getCrossPoints(Circle c1, Circle c2){
    double d = (c1.c - c2.c).abs();
    double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    double t = arg(c2.c - c1.c);
    return make_pair(c1.c + polar(c1.r, t + a), c1.c + polar(c1.r, t - a));
}
 
bool comp(const Point &a, const Point &b){
    return a.x < b.x;
}
 
int main(){
    for(;;){
        scanf("%d", &N);
        if(N == 0) break;
        for(int i = 0; i < N; i++){
            scanf("%lf %lf", &p[i].x, &p[i].y);
        }
        sort(p, p + N, comp);
        int res = 1;
        for(int i = 0; i < N; i++){
            for(int j = i + 1; j < N; j++){
                if(p[j].x - p[i].x > 2.0) break;
                else if(getDistance(p[i], p[j]) > 2.0) continue;
                pair<Point, Point> pp = getCrossPoints((Circle){p[i], 1.0}, (Circle){p[j], 1.0});
                Point p1 = pp.first, p2 = pp.second;
                int cnt1 = 2, cnt2 = 2;
                for(int k = 0; k < N; k++){
                    if(k == i || k == j) continue;
                    if(p[k].x - p[j].x > 1.0) break;
                    if(getDistance(p1, p[k]) < 1.0) cnt1++;
                    if(getDistance(p2, p[k]) < 1.0) cnt2++;
                }
                res = max(res, max(cnt1, cnt2));
            }
        }
        printf("%d\n", res);
    }
    return 0;
}