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; }
一个圆里面有一些点,然后用一条直径把圆切成两半,这样哪一半里面的点多就取哪一半。只要枚举每一个圆内的点,将其与圆心的连线作为切割的直径,然后运用叉积判断剩下的每个点是在这条直径的左边还是右边就能计算出左右两个半圆各包含了多少个点了。(如果那个点是圆心,不用考虑)
相关文章推荐
- Android 手把手教您自定义ViewGroup(一)
- ios事件传递和响应
- CardView 的使用
- [Hibernate系列—] 2. 创建SessionFactory 与 Session
- oracle 常用操作
- 解决系统提示msvcr71.dll文件丢失的错误
- System类
- springmvc demo
- java array 与补码
- 初识面向过程与面向对象
- Java并发编程:线程和进程的创建(转)
- 私信功能方案一(一张表)
- Android开发入门之Android开发工具原生包NDK
- [UnityUI]UGUI新手引导
- Java编程之脚本语言的使用
- MFC连接数据库出现Stack around the variable 'myCont' was corrupted错误
- 大数据风控 ——互联网消费金融的必由之路
- Android进程通信之一:两种序列化方式
- datatable使用
- ♥codeforces 627A-XOR Equation【数学】