SPOJ 149 FSHEEP Fencing in the Sheep ( 计算几何 + 二分 )
以下摘自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 ( 计算几何 + 二分 )的更多相关文章
- 【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流
题目描述 WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线 ...
- 洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)
题面 传送门 题解 题目转化一下就是所有点都在直线\(Ax+By-C=0\)的同一侧,也就可以看做所有点代入\(Ax+By-C\)之后的值符号相同,我们只要维护每一个点代入直线之后的最大值和最小值,看 ...
- 【POJ】2318 TOYS ——计算几何+二分
TOYS Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10281 Accepted: 4924 Description ...
- BZOJ_1020_[SHOI2008]_安全的航线flight_(计算几何+二分)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1020 给出一条航线(折线),给出\(c\)个陆地(多边形).求航线上距离陆地的最近距离最远的距 ...
- hdu 4033 Regular Polygon 计算几何 二分+余弦定理
题目链接 给一个n个顶点的正多边形, 给出多边形内部一个点到n个顶点的距离, 让你求出这个多边形的边长. 二分边长, 然后用余弦定理求出给出的相邻的两个边之间的夹角, 看所有的加起来是不是2Pi. # ...
- 牛客第二场 C.message(计算几何+二分)
题目传送:https://www.nowcoder.com/acm/contest/140/C 题意:有n个云层,每个云层可以表示为y=ax+b.每个飞机的航线可以表示为时间x时,坐标为(x,cx+d ...
- 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 ...
- 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 ...
- 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 ...
随机推荐
- Map详解
https://mp.weixin.qq.com/s/s4KLQyE5bY833kGzWl3vsg
- 深入浅出:了解JavaScript中的call,apply,bind的差别
在 javascript之 this 关键字详解文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变 ...
- mysql 自增主键为什么不是连续的?
由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑 MyISAM 引擎的自增值保存在数据文件中 nnoDB 引擎的自增值,其实是保存在了内存里,并且到了 MySQL 8.0 ...
- ORM初级实战简单的数据库交互
setting.py中: """ Django settings for untitled3 project. Generated by 'django-admin st ...
- Yii2实现跨mysql数据库关联查询排序功能
遇到一个项目,需要跨表网上找了很多的资料,整理一下,方便以后再次使用 背景:在一个mysql服务器上(注意:两个数据库必须在同一个mysql服务器上)有两个数据库: memory (存储常规数据表) ...
- 【yii2】rules规则的默认值
ExampleModel.php /** * {@inheritdoc} */ public function rules() { return [ ['updated_at','default',' ...
- 深入理解PHP数组函数和预定义接口
一. PHP对数组的过滤 函数: array_filter(p1[,p2]) 参数p1是要过滤的数组,参数p2是自定义过滤会掉函数(可以是匿名函数) 例子: <?php $arr = ['',n ...
- MySQL安装在Linux
利用Alt+p工具将下载好的Linux版本的mysql软件加载到根目录. 1. 将下载好的MySQL文件MySQL-5.6.41-1.el6.i686.rpm-bundle.tar放到 根目录下的mk ...
- elasticsearch 5.x 系列之一 开始安装啦
以下是镇楼用的,各路退让,我要吹liubi 了 // // _oo0oo_ // o8888888o // 88" . "88 // (| -_- |) // 0\ = /0 // ...
- 学习Pytbon第九天,函数1 过程和参数
函数def func1():定义函数 '''testing1'''#函数的说明 print("in the func1")#定义过程 return 0 #得到函数的执行结果.还是程 ...