SGU 253 判断点在凸包内

来源:互联网 发布:下载了wpsoffice软件 编辑:程序博客网 时间:2024/06/03 14:32

贴个模板,极角排序+二分。。。。

这个大牛的博客说的很好:http://hi.baidu.com/aekdycoin/item/2d54f9c0fef55457ad00efd6

代码来源http://blog.csdn.net/codeforces_sphinx/article/details/7200301

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <string>#include <vector>#include <cmath>#include <queue>#include <stack>using namespace std;typedef double LF;typedef __int64 LL;typedef unsigned __int64 ULL;const double eps = 10e-7;const double PI = acos(-1.0);const int MAXN = 100004;int n, m, k;struct Point{int x, y;}pnt[MAXN];struct Segment{int vx, vy;Segment() {}Segment(Point po, Point pt){vx = pt.x - po.x;vy = pt.y - po.y;}LL operator * (const Segment & rhs) const{return LL(vx) * LL(rhs.vx) + LL(vy) * LL(rhs.vy);}LL operator ^ (const Segment & rhs) const{return LL(vx) * LL(rhs.vy) - LL(vy) * LL(rhs.vx);}};bool cmpXY(const Point & lhs, const Point & rhs){return lhs.y != rhs.y ? lhs.y < rhs.y : lhs.x < rhs.x;}bool cmpPK(const Point & lhs, const Point & rhs){return (Segment(pnt[0], lhs) ^ Segment(pnt[0], rhs)) > 0;}bool inPolygon(const Point & pt){int low = 1, high = n - 2, mid = (low + high) / 2, res = -1;bool sign = false;int token;LL flag[2];while (low <= high){mid = (low + high) / 2;flag[0] = (Segment(pnt[0], pt) ^ Segment(pnt[0], pnt[mid]));if (0 == flag[0]){sign = true;token = mid;break ;}flag[1] = (Segment(pnt[0], pt) ^ Segment(pnt[0], pnt[mid + 1]));if (0 == flag[1]){sign = true;token = mid + 1;break ;}if (flag[0] < 0 && flag[1] > 0 || flag[0] > 0 && flag[1] < 0){res = mid;break ;}if (flag[0] < 0 && flag[1] < 0){low = mid + 1;}else{high = mid - 1;}}if (sign){if ((Segment(pnt[0], pt) * Segment(pnt[token], pt)) <= 0){return true;}return false;}if (-1 == res){return false;}return (Segment(pnt[mid], pt) ^ Segment(pnt[mid], pnt[mid + 1])) <= 0;}int main(){Point pt;int cnt;while (scanf("%d %d %d", &n, &m, &k) != EOF){for (int i = 0; i < n; ++i){scanf("%d %d", &pnt[i].x, &pnt[i].y);}sort(pnt, pnt + n, cmpXY);sort(pnt + 1, pnt + n, cmpPK);pnt[n] = pnt[0];cnt = 0;while (m--){scanf("%d %d", &pt.x, &pt.y);if (inPolygon(pt)){++cnt;}}puts(cnt >= k ? "YES" : "NO");}return 0;}


原创粉丝点击