您的位置:首页 > 其它

POJ 1106 扫描与OnLeft函数的使用

2016-03-15 16:29 239 查看
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
struct Point
{
double x, y;
Point(double x = 0, double y = 0): x(x), y(y) {}
};
typedef Point Vector;
typedef vector<Point> Polygon;
Vector operator +(Vector A, Vector B)//
{
return Vector(A.x + B.x, A.y + B.y);
}
Vector operator -(Point A, Point B)//
{
return Vector(A.x - B.x , A.y - B.y);
}
Vector operator *(Vector A, double p)//
{
return Vector(A.x * p, A.y * p);
}
Vector operator /(Vector A, double p)//
{
return Vector(A.x / p, A.y / p);
}
bool operator <(const Point &a, const Point &b)//
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
const double eps = 1e-10;
int dcmp(double x)//
{
if (fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
bool operator ==(const Point &a, const Point &b)//
{
return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
double Dot(Vector A, Vector B)//
{
return A.x * B.x + A.y * B.y;
}
double Length(Vector A)//
{
return sqrt(Dot(A, A));
}
double Cross(Vector A, Vector B)//
{
return A.x * B.y - A.y * B.x;
}
double Angle(Vector A, Vector B)//
{
return acos(Dot(A, B) / Length(A) / Length(B));
}
double Area2(Point A, Point B, Point C) //
{
return Cross(B - A, C - A);
}
double TriArea(Point A, Point B, Point C) //
{
return fabs(Cross(B - A, C - A)) / 2;
}
int Distance2(Point A, Point B)
{
return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
}
struct Line
{
Point P;
Vector v;
double ang;
Line() {};
Line(Point P, Vector v): P(P), v(v) {ang = atan2(v.y, v.x);}
bool operator < (const Line& L) const
{
return ang < L.ang;
}
};
bool OnLeft(Line L, Point p)
{
return Cross(L.v, p - L.P) > 0;
}
Point P;
std::vector<Point> v;
double R;
int n;
Point read_point()
{
double X, Y;
scanf("%lf%lf", &X, &Y);
return Point(X, Y);
}
int main(int argc, char const *argv[])
{
while (P = read_point(), scanf("%lf", &R) && dcmp(R) > 0)
{
int ans = 0;
v.clear();
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
Point t = read_point();
if (dcmp(Distance2(t, P) - R * R) <= 0)
v.push_back(t);
}
for (int i = 0; i < v.size(); i++)
{
if (dcmp(Distance2(v[i], P)) <= 0) continue;
Line L(P, v[i] - P);
int cntL = 1, cntR = 1;
for (int j = 0; j < v.size(); j++) if (j != i)
if (OnLeft(L, v[j])) cntL++; else cntR++;
ans = max(ans, max(cntL, cntR));
}
printf("%d\n", ans);
}
return 0;
}


一个圆里面有一些点,然后用一条直径把圆切成两半,这样哪一半里面的点多就取哪一半。只要枚举每一个圆内的点,将其与圆心的连线作为切割的直径,然后运用叉积判断剩下的每个点是在这条直径的左边还是右边就能计算出左右两个半圆各包含了多少个点了。(如果那个点是圆心,不用考虑)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: