以下摘自SPOJ泛做表格:

题意:给定一个星形多边形,而且给出了一个可以看到形内所有点的位置(我们称这个点为观察点),让你判断有多少个点位于多边形内。

时间复杂度:O(mlogn)

将多边形上的点按极角排序,观察点与多边形上任意相邻两点形成若干个三角形,再按照极角查找给定点可能位于哪个三角形,最后用叉积判断它是否真的在那个三角形内。

注意细节,给几组数据:

input


-
-
- - -
- - -
-
-
-
-
-
- -
- -
- -
- -
- -
-
-
-
-
- -
- - -
-
-
- - -
- -
- - -
- -
- -
-
-
- -
-
- -
- -
-
-
- -
-
- -
- -
- - -

output


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm> using namespace std; const double eps = 1e-;
const double PI = acos( -1.0 );
const int MAXN = ; int dcmp( double x ) //控制精度
{
if ( fabs(x) < eps ) return ;
else return x < ? - : ;
} struct Point
{
double x, y;
double ang; //极角
int id;
Point( double x = , double y = ):x(x), y(y) { }
void readPoint()
{
scanf("%lf%lf", &x, &y );
return;
}
void GetAngle()
{
ang = atan2( y, x );
if ( dcmp( ang ) < ) ang = PI + PI+ ang;
return;
}
void showP()
{
printf( "(%.6f, %.6f): ang=%.6f id=%d\n", x, y, ang, id );
return;
}
}; typedef Point Vector; Vector operator+( Vector A, Vector B ) //向量加
{
return Vector( A.x + B.x, A.y + B.y );
} Vector operator-( Vector A, Vector 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 dcmp( A.x - B.x) < || ( dcmp(A.x - B.x ) == && dcmp( A.y - B.y ) < );
} bool operator>( const Point& A, const Point& B ) //两点比较大于
{
return dcmp( A.x - B.x) > || ( dcmp(A.x - B.x ) == && dcmp( A.y - B.y ) > );
} bool operator==( const Point& a, const Point& b ) //两点相等
{
return dcmp( a.x - b.x ) == && dcmp( a.y - b.y ) == ;
} 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 Angle( Vector A, Vector B ) //向量夹角
{
return acos( Dot(A, B) / Length(A) / Length(B) );
} double Cross( Vector A, Vector B ) //向量叉积
{
return A.x * B.y - A.y * B.x;
} bool OnSegment( Point p, Point a1, Point a2 ) //点在线段上,不包含端点
{
return dcmp( Cross(a1 - p, a2 - p) ) == && dcmp( Dot( a1 - p, a2 - p ) ) < ;
} int N, M;
Point Poly[MAXN];
int Dcnt; //找到第一个大于的
void BiSearch( double tar, int l, int r, int& u, int& v )
{
//printf("%.6f %.6f %.6f\n", tar, Poly[1].ang, Poly[N].ang );
if ( dcmp( tar - Poly[].ang ) <= || dcmp( tar - Poly[N].ang ) >= )
{
u = N;
v = ;
return;
}
int mid;
int ans = N;
while ( l <= r )
{
mid = ( l + r ) >> ;
if ( dcmp( Poly[mid].ang - tar ) > )
{
ans = mid;
r = mid - ;
}
else l = mid + ;
}
v = ans;
u = v - ;
return;
} bool cmp( Point a, Point b )
{
if ( dcmp( a.ang - b.ang ) != )
return dcmp( a.ang - b.ang ) < ;
return a.id < b.id;
} void init()
{
scanf( "%d%d", &N, &M );
Dcnt = ;
for ( int i = ; i <= N; ++i )
{
Poly[i].readPoint();
Poly[i].GetAngle();
Poly[i].id = i;
}
sort( Poly + , Poly + + N, cmp );
Poly[] = Poly[N];
Poly[].ang -= *PI;
Poly[N+] = Poly[];
Poly[N+].ang += *PI;
return;
} bool check( Point a, Point *p )
{
if ( a == p[] || a == p[] || a == p[] ) return true;
if ( OnSegment( a, p[], p[] ) ) return true;
if ( OnSegment( a, p[], p[] ) ) return true;
if ( OnSegment( a, p[], p[] ) ) return true;
int pre = dcmp( Cross( p[] - p[], a - p[] ) );
for ( int i = ; i < ; ++i )
{
int tmp = dcmp( Cross( p[i + ] - p[i], a - p[i] ) );
if ( tmp != pre ) return false;
}
return true;
} int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T;
scanf( "%d", &T );
while ( T-- )
{
init(); int ans = ;
Point sanjiao[];
sanjiao[] = Point(, );
for ( int i = ; i < M; ++i )
{
Point p;
p.readPoint();
p.GetAngle();
int u, v;
BiSearch( p.ang, , N, u, v );
sanjiao[] = Poly[u];
sanjiao[] = Poly[v];
//printf( "u=%d v=%d\n", u, v );
if ( check( p, sanjiao ) )
{
++ans;
continue;
}
while ( dcmp( Poly[u-].ang - p.ang ) == && u != v )
{
--u;
if ( u == ) u = N;
//printf( "**u=%d v=%d\n", u, v );
sanjiao[] = Poly[u];
sanjiao[] = Poly[v];
if ( check( p, sanjiao ) )
{
++ans;
break;
}
}
}
printf( "%d\n", ans );
}
return ;
}

SPOJ 149 FSHEEP Fencing in the Sheep ( 计算几何 + 二分 )的更多相关文章

  1. 【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流

    题目描述 WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线 ...

  2. 洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)

    题面 传送门 题解 题目转化一下就是所有点都在直线\(Ax+By-C=0\)的同一侧,也就可以看做所有点代入\(Ax+By-C\)之后的值符号相同,我们只要维护每一个点代入直线之后的最大值和最小值,看 ...

  3. 【POJ】2318 TOYS ——计算几何+二分

    TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description ...

  4. BZOJ_1020_[SHOI2008]_安全的航线flight_(计算几何+二分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1020 给出一条航线(折线),给出\(c\)个陆地(多边形).求航线上距离陆地的最近距离最远的距 ...

  5. hdu 4033 Regular Polygon 计算几何 二分+余弦定理

    题目链接 给一个n个顶点的正多边形, 给出多边形内部一个点到n个顶点的距离, 让你求出这个多边形的边长. 二分边长, 然后用余弦定理求出给出的相邻的两个边之间的夹角, 看所有的加起来是不是2Pi. # ...

  6. 牛客第二场 C.message(计算几何+二分)

    题目传送:https://www.nowcoder.com/acm/contest/140/C 题意:有n个云层,每个云层可以表示为y=ax+b.每个飞机的航线可以表示为时间x时,坐标为(x,cx+d ...

  7. hdu 3264 09 宁波 现场 E - Open-air shopping malls 计算几何 二分 圆相交面积 难度:1

    Description The city of M is a famous shopping city and its open-air shopping malls are extremely at ...

  8. HDU 3264/POJ 3831 Open-air shopping malls(计算几何+二分)(2009 Asia Ningbo Regional)

    Description The city of M is a famous shopping city and its open-air shopping malls are extremely at ...

  9. Codeforces gym102058 J. Rising Sun-简单的计算几何+二分 (2018-2019 XIX Open Cup, Grand Prix of Korea (Division 2))

    J. Rising Sun time limit per test 1.0 s memory limit per test 1024 MB input standard input output st ...

随机推荐

  1. css3之Media Queries 媒体查询

    一.初步了解 Media Queries是CSS3新增加的一个模块功能,其最大的特点就是通过css3来查询媒体,然后调用对应的样式. 了解Media Queries之前需要了解媒体类型以及媒体特性: ...

  2. Java 压缩文件夹工具类(包含解压)

    依赖jar <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons ...

  3. Bean的初始化和销毁

    在我们实际开发的时候,经常会遇到在Bean在使用之前或者之后做些必要的操作,Spring对Bean的生命周期的操作提供了支持.在使用Java配置和注解配置下提供如下两种方式.    1.Java配置方 ...

  4. 一篇SSM框架整合友好的文章(一)

    转载请标明出处: http://blog.csdn.net/forezp/article/details/53730333 本文出自方志朋的博客 最近实在太忙,之前写的<rxjava系列文章&g ...

  5. poj_1995_Raising Modulo Numbers

    Description People are different. Some secretly read magazines full of interesting girls' pictures, ...

  6. 分享spring、spring boot、spring cloud一些学习资源,从基础知识到项目实战

    1.spring注解驱动开发,学习spring boot和spring cloud必备知识 链接: https://pan.baidu.com/s/1xhULzLlpkERhoMi1G5Lgfg 密码 ...

  7. scrapy--Beautyleg

    很早就开始关注:Beautyleg 高清丝袜美腿.关注之后开始觉得打开了新世界的大门,如果有相同观点的,那么你很有品味.说真的,学习爬虫的动力之一就是想把里面的图片爬取下来.哈哈哈!!! 给大家放点爬 ...

  8. POJ:3273-Monthly Expense

    Monthly Expense Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 32067 Accepted: 12081 Des ...

  9. 笔记-爬虫-selenium常用方法

    笔记-爬虫-selenium常用方法 1.      查找元素 常用的查找方法 find_element_by_name find_element_by_xpath find_element_by_l ...

  10. Echarts 背景渐变柱状图

    var dom = document.getElementById("container"); var myChart1 = echarts.init(dom); var app ...