SGU 253. Theodore Roosevelt
来源:互联网 发布:薛定谔的猫 知乎 编辑:程序博客网 时间:2024/05/19 13:43
题目:http://acm.sgu.ru/problem.php?contest=0&problem=253
本题要求在一个给定凸包,一些点有几个是在凸包内的(包括边界)。
以前判断某一点是否在多边形内,可以叉积依次求面积的方法,但是每次查询耗时O(n)。
所以这里提一种每次查询只需要O(lgn)的解法。
就是先按极角排序,然后二分求给定点的极角范围,叉积计算进行求解。
一开始我的线段拐向求反了,导致wa on test 5。一定要小心啊。
而且swap写的一开始也有问题,谢学弟帮我排bug。二分法的临界仍然需要熟练掌握。是在担心写错,就直接用STL upper_bound吧。不要自己写了。
http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html
#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <algorithm>using namespace std;const double eps = 1e-8;struct Point{ long long x; long long y; double angle; long long dis; Point() {} Point(long long _x,long long _y):x(_x),y(_y) {} friend Point operator + (Point a,Point b) { return Point(a.x+b.x , a.y+b.y); } friend Point operator - (Point a,Point b) { return Point(a.x-b.x , a.y-b.y); }};int dcmp(double x){ if(fabs(x)<eps) { return 0; } return x>0?1:-1;}double det(Point a,Point b){ return a.x*b.y-a.y*b.x;}double det(Point a,Point b,Point o){ return det(a-o,b-o);}double det(Point a,Point b,Point c,Point d){ return det(b-a,d-c);}Point p[100005];bool cmp(Point a,Point b){ return dcmp(a.angle-b.angle)<0 || (dcmp(a.angle - b.angle)==0 && a.dis <b.dis);}void swap(Point &a,Point &b){ Point c = b; b = a; a = c;}int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin);#endif int n,m,k; while(scanf(" %d %d %d",&n,&m,&k)!=EOF) { Point le; int le_num = 0; for(int i=0;i<n;i++) { scanf(" %lld %lld",&p[i].x,&p[i].y); //求最下左点 if(i==0) { le.x = p[0].x; le.y = p[0].y; le_num = 0; } else { if(p[i].y<le.y || (p[i].y == le.y && p[i].x < le.x)) { le = p[i]; le_num = i; } } } swap(p[0],p[le_num]); for(int i=1;i<n;i++) { p[i].angle = atan2(p[i].y - p[0].y,p[i].x - p[0].x); p[i].dis = (p[i].x - p[0].x)*(p[i].x - p[0].x) + (p[i].y - p[0].y)*(p[i].y - p[0].y); } sort(p+1,p+n,cmp); int x,y; int num = 0; for(int i=0;i<m;i++) { Point temp; scanf(" %lld %lld",&temp.x,&temp.y); if(temp.x == p[0].x && temp.y == p[0].y) { num++; } else { temp.angle = atan2(temp.y-p[0].y,temp.x-p[0].x); int low = 1; int high = n-1; if(dcmp(temp.angle - p[high].angle)>0 || dcmp(temp.angle - p[low].angle)<0) { continue; } int pos = 1; //求upper_bound while(low<high) { int mid = (low + high)/2; if( p[mid].angle <= temp.angle) { low = mid + 1; pos = low; } else { high = mid; pos = high; } } if(pos == n) { pos--; } if(det(temp,p[pos -1],p[pos])>=0) { num++; } } } if(num>=k) { printf("YES\n"); } else { printf("NO\n"); } } return 0;}参考:http://hi.baidu.com/aekdycoin/item/2d54f9c0fef55457ad00efd6
- SGU 253. Theodore Roosevelt
- SGU 253. Theodore Roosevelt
- sgu-253 Theodore Roosevelt
- sgu Theodore Roosevelt【判断点是否在凸多边形内模板】
- sgu253:Theodore Roosevelt(扫描线)
- SAT作文素材Eleanor Roosevelt
- SGU
- SGU
- SGU
- SGU
- SGU
- SGU
- (SGU
- SGU
- SGU
- SGU
- SGU
- SGU
- 单例运行
- KNN学习笔记
- 打不如疼
- 求数组中元素的和
- 用正则表达式验证用户名密码
- SGU 253. Theodore Roosevelt
- 简单工厂模式及工厂模式
- 建立CE 连接
- C语言:sizeof(结构体)
- [Learning] SAM
- Java中两种字符串初始化方法的区别
- C语言实现出入栈操作
- chapter 2.1: 什么是windows Driver
- C#操作Word (1)Word对象模型