第二场B
B.Boundary



示例1
输入
4
1 1
0 2
2 0
2 2
输出
3
说明

————————————————————————————————————————————————
意思:平面上,所有边过点(0,0)的圆中,找出边上有最多给出的点的圆,输出最多点的数目。
输入点的数目n,然后输入各个点的坐标(xi,yi)
题解思路
1.

2.
还看到一个用三点共圆公式的,同样是法1的枚举,只不过是改成枚举计算圆心,然后找这些圆心的众数。
给的标程(注释是自己的理解。。理解的不一定对。。)
#include <cstdio> #include <algorithm> using namespace std; typedef long long LL; typedef __int128_t LLL; #define N 2000 + 5 int n, ans = 1, X[N], Y[N]; struct Frac { LL fz, fm; Frac() : Frac(0, 1){} Frac(LL fz, LL fm) : fz(fz), fm(fm) {}//构造函数 bool operator < (const Frac &rhs)//运算符重载 { return (LLL) fz * rhs.fm < (LLL) fm * rhs.fz; } bool operator == (const Frac &rhs) { return (LLL) fz * rhs.fm == (LLL) fm * rhs.fz; } }A[N]; int Cross(int lhs, int rhs)//叉乘 { return X[lhs] * Y[rhs] - X[rhs] * Y[lhs]; } int Dot(int lhs, int rhs)//点乘 { return X[lhs] * X[rhs] + Y[lhs] * Y[rhs]; } int Dis2(int lhs, int rhs)//两点距离平方 { int dx = X[lhs] - X[rhs], dy = Y[lhs] - Y[rhs]; return dx * dx + dy * dy; } int Sgn(int x)//判断正负 { if (x > 0) return 1; if (x < 0) return -1; return 0; } Frac GetCosAngle2(int i, int j) { int a2 = Dis2(0, i), b2 = Dis2(i, j), c2 = Dis2(0, j); int sgn = Sgn(b2 + c2 - a2); return Frac(1LL * sgn * (b2 + c2 - a2) * (b2 + c2 - a2), 4LL * b2 * c2); } int main() { scanf("%d", &n); for (int i = 1; i <= n; i ++) scanf("%d%d", X + i, Y + i); for (int i = 1; i <= n; i ++)//枚举第一个点P { int cnt = 0; for (int j = 1; j <= n; j ++)//枚举除P外的点 if (Cross(i, j) > 0) A[++ cnt] = GetCosAngle2(i, j); sort(A + 1, A + cnt + 1); for (int l = 1, r; l <= cnt; l = r) { for (r = l; A[l] == A[r] && r <= cnt; r ++) ; ans = max(ans, r - l + 1);//找众数并计数,赋值给ans } } printf("%d\n", ans); return 0; }
浙公网安备 33010602011771号