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; }