読者です 読者をやめる 読者になる 読者になる

UVa12240 Cocircular Points

解法
テストケースが書いていないが、3点より特定した一つの円の周上に1点が乗っかるか調べる O(N^4) の解法で正答できるようになっている。

3点から一つの円を特定する方法は垂直二等分線の交点である。
2点のペアの中点と、その2点のペアのベクトルを90度回転させた時の点とを結ぶ直線を考えて、その2つの直線の交点を求める。

#include <cstdio>
#include <algorithm>
#include <complex>
#include <vector>
#include <numeric>

using namespace std;

#define X real()
#define Y imag()

#define SQ(x) ((x)*(x))

double const EPS = 1e-7;

typedef complex<double> P;

double dist2(P a, P b) {
  return SQ(a.X - b.X) + SQ(a.Y - b.Y);
}

double cross(P a, P b) {
  return a.X*b.Y - a.Y*b.X;
}

P getPointLL(P a1, P a2, P b1, P b2) {
  P a = a2 - a1, b = b2 - b1;
  return a1 + a*cross(b, b1-a1) / cross(b, a);
}

P getCenterOfCircle(P a, P b, P c) {
  P mab = (a+b)/2.;
  P mbc = (b+c)/2.;
  P vab = (b-a)*P(0,1), vbc = (c-b)*P(0,1);
  return getPointLL(mab, mab+vab, mbc, mbc+vbc);
}
int main() {
  
  int N;
  while(scanf("%d", &N) && N) {
    vector<P> in;
    for(int i=0; i<N; i++) {
      double x, y;
      scanf("%lf %lf", &x, &y);
      in.push_back(P(x, y));
    }
    
    int ans = 0;
    for(int i=0; i<N; i++)
      for(int j=i+1; j<N; j++)
        for(int k=j+1; k<N; k++) {
          P center = getCenterOfCircle(in[i], in[j], in[k]);
          double R2 = dist2(center, in[i]);
          int cnt = 0;
          for(int l=0; l<N; l++) {
            if(abs(dist2(in[l], center)-R2) < EPS) { cnt++; }
          }
          ans = max(ans, cnt);
        }
    
    printf("%d\n", max(ans, min(2, N)));
  }
  return 0;
}