Boundary(几何)
程序员文章站
2021-12-17 21:54:12
...
题意:用原点和给出的任意两点作圆,问所作的圆最多可以同时通过几个点。
做法:过三点做出所有圆,因为原点在圆上,则半径一定,所以如果圆心相同,那么这几个圆就是相同的。三点中有一点确定是原点,另外两遍遍历所有的点的组合即可,耗时O(n2),然后找出哪个圆心出现最多次,记为num,假设该圆过了ans个点,每次和圆确定一个圆需要从ans个点中取出两个点,这不就是排列组合那味了吗?所以C(ans,2)=mum,即ans*(ans-1)/2=num.
#include<cstdio>
#include <iostream>
#include <cstring>
#include <deque>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
using namespace std;
double Pointx, Pointy;
struct Point
{
double x, y;
}point[2010];
void get_center(Point a, Point b, Point c)
{
double fm1 = 2 * (a.y - c.y) * (a.x - b.x) - 2 * (a.y - b.y) * (a.x - c.x);
double fm2 = 2 * (a.y - b.y) * (a.x - c.x) - 2 * (a.y - c.y) * (a.x - b.x);
if (fm1 == 0 || fm2 == 0)//判断是否三点一线
{
Pointx = Pointy = -1;
return;
}
double fz1 = a.x * a.x - b.x * b.x + a.y * a.y - b.y * b.y;
double fz2 = a.x * a.x - c.x * c.x + a.y * a.y - c.y * c.y;
Pointx = (fz1 * (a.y - c.y) - fz2 * (a.y - b.y)) / fm1;
Pointy = (fz1 * (a.x - c.x) - fz2 * (a.x - b.x)) / fm2;
}
vector<pair<double, double>> vec;
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lf %lf", &point[i].x, &point[i].y);
}
Point O;
O.x = O.y = 0;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
get_center(O, point[i], point[j]);
if (Pointx == Pointy && Pointx==-1)
continue;
vec.push_back({ Pointx, Pointy });
}
}
if (vec.size() == 0) {
printf("1\n");
return 0;
}
sort(vec.begin(), vec.end());
int sum = 1;
int num = 1;
pair<double, double> now = vec[0];
for (int i = 1; i < vec.size(); i++) {
if (vec[i] == now) ++num;
else {
now = vec[i];
sum = max(sum, num);
num = 1;
continue;
}
sum = max(sum, num);
}
for (int i = 1; i <= n; i++) {
if (i * (i - 1) == sum * 2) {
printf("%d\n", i);
return 0;
}
}
return 0;
}
借鉴于(虽说是借鉴,但感觉差别不是很大)
上一篇: javascript倒计时
下一篇: 判断四个点是否共平面,Python实现