POJ 2318 几何二分

来源:互联网 发布:最优化算法 pdf 编辑:程序博客网 时间:2024/05/22 17:12
#include <cstdio>#include <cstring>#include <iostream>#include <vector>#include <cmath>using namespace std;const int maxn = 5E3 + 10;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);}Point read_point(){int x, y;scanf("%d%d", &x, &y);return Point(x, 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;}int n, m, X1, Y1, X2, Y2, kase, Ui, Li, ans[maxn];Point P;Line L[maxn];int main(int argc, char const *argv[]){while (~scanf("%d", &n) && n){if (kase) printf("\n"); else kase++;memset(ans, 0, sizeof(ans));scanf("%d%d%d%d%d", &m, &X1, &Y1, &X2, &Y2);for (int i = 1; i <= n; i++){scanf("%d%d", &Ui, &Li);L[i] = Line(Point(Ui, Y1), Point(Li, Y2) - Point(Ui, Y1));}L[0]  =  Line(Point(X1, Y1), Point(X1, Y2) - Point(X1, Y1));L[n + 1] = Line(Point(X2, Y1), Point(X2, Y2) - Point(X2, Y1));for (int i = 0; i < m; i++){P = read_point();int l = 0, r = n + 1, mid = (l + r) / 2;while (l <= r){if (OnLeft(L[mid], P)) l = mid + 1;else r = mid - 1;mid = (l + r) / 2;}ans[mid]++;}for (int i = 0; i <= n; i++)printf("%d: %d\n", i, ans[i]);}return 0;}


就是给了m个点,落在n+1个区域中,问各个区域有多少个点。

加上左右边框,二分用OnLeft判断在直线的那一侧。

0 0
原创粉丝点击