Cocircular Points
.
.
题意:给定n个点,问最多有多少个点在一个圆上。
.
.
解法:n^3枚举三角形,每一个三角形确定一个外接圆,然后把圆的圆心和半径记录下来,统计一下最多出现的就好了。
.
.
队友代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=100+5;
const int maxp=maxn*maxn*maxn;
const double eps=1e-7;
struct Point {
double x, y;
void read() {scanf("%lf%lf", &x, &y);}
Point() {}
Point(double x, double y): x(x), y(y) {}
} p[maxn], dif[maxn][maxn], md[maxn][maxn];
int C[maxn];
void init() {
for (int i=3; i<maxn; i++) {
C[i]=i*(i-1)*(i-2)/6;
}
}
double Cross(Point a, Point b) {
return a.x*b.y-a.y*b.x;
}
struct Node{
Point pnt; double r;
} a[maxp];
inline bool cmp(Node l, Node r) {
if (fabs(l.pnt.x-r.pnt.x)>eps) return l.pnt.x<r.pnt.x;
else if (fabs(l.pnt.y-r.pnt.y)>eps) return l.pnt.y<r.pnt.y;
else return l.r<r.r;
}
Point GetLineIntersection(Point p, Point v, Point q, Point w) {
Point u(p.x-q.x, p.y-q.y);
double t=Cross(w, u)/Cross(v, w);
return Point(p.x+v.x*t, p.y+v.y*t);
}
int main() {
int n;
init();
while (scanf("%d", &n)==1) {
if (!n) return 0;
int ans=0, cnt=0;
for (int i=0; i<n; i++) p[i].read();
for (int i=0; i<n; i++)
for (int j=0; j<n; j++) {
dif[i][j].x=p[j].y-p[i].y;
dif[i][j].y=p[i].x-p[j].x;
md[i][j].x=(p[i].x+p[j].x)/2.;
md[i][j].y=(p[i].y+p[j].y)/2.;
}
for (int i=0; i<n; i++)
for (int j=i+1; j<n; j++)
for (int k=j+1; k<n; k++) {
if (fabs(Cross(dif[i][j], dif[j][k]))>eps) {
Point tmp=GetLineIntersection(md[i][j], dif[i][j], md[j][k], dif[j][k]);
double rr=hypot(tmp.x-p[i].x, tmp.y-p[i].y);
a[cnt++]=(Node){tmp, rr};
}
}
sort(a, a+cnt, cmp);
for (int i=0; i<cnt; ) {
int j=i+1;
while (j<cnt&&fabs(a[i].pnt.x-a[j].pnt.x)<eps&&fabs(a[j].pnt.y-a[i].pnt.y)<eps&&fabs(a[j].r-a[i].r)<eps) j++;
ans=max(ans, j-i);
i=j;
}
// cout << ans << endl;
if (ans==0) puts(n<2?"0":"2");
else for (int i=3; i<maxn; i++) if (C[i]==ans) {
printf("%d\n", i); break;
}
}
}