UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)
Saint John Festival
题目链接:
http://acm.hust.edu.cn/vjudge/contest/127406#problem/J
Description
```
Porto’s Festa de São João is one of Europe’s liveliest street
festivals. Its peak is the night of 23rd to 24th of June, with
dancing parties from Ribeira to Foz all night long.
Time to celebrate, with friends, relatives, neighbours or
simply with other people in streets, armed with colored plastic
hammers, huge garlic flowers or a bunch of lemongrass
to gently greet passers-by. Fireworks, grilled sardines, barbecues,
bonfires, potted basil plants (manjericos) and the
sky covered by incandescent sky lanterns (balões de S.João)
launched from every corner make this party unique.
The sky lanterns are made of thin paper and cannot be
released until they are filled in with hot air. Sometimes they
burn out still on ground or on the way up, if a sudden gust
of wind catches them. For this reason, the successful launchers
usually follow the movement of their sky lanterns, with a
mixture of anxiety and joy, for as long as they can distinguish
them in the sky.
We are not aware of any attempt to achieve a Guinness
record of sky lanterns launched simultaneously (it could be
dreadful night for firemen if there were).
Can you imagine, thousands of people preparing their sky
lanterns for release at the city park, within a region of larger ones that will be launched simultaneously?
The large sky lanterns can be used to identify their positions in the sky afterwards, in order to
count the surviving ones at an observation instant.
Given the positions of the large sky lanterns and the positions of the small ones, determine the
number of small sky lanterns that are in the interior or on the boundary of some triangle defined by
any three of the large ones.
```
Input
The input file contains several test cases, each of them as described below.
The first line has an integer L that defines the number of the large sky lanterns at the observation
instant. Each of the following L lines contains a pair of integers separated by a space that gives the
coordinates (x, y) of a large sky lantern. After that, there is a line with an integer S that defines the
number of small sky lanterns and S lines, each defining the position of a small sky lantern. The height
is irrelevant for us. All the given points are distinct and there are at least three points representing
large sky lanterns that are not collinear.
Output
For each test case, the output has a single line with the number of small sky lanterns that are in the
interior or on the boundary of some triangle defined by any three of the large sky lanterns.
Constraints:
3 ≤ L ≤ 10 000 Number of large sky lanterns.
1 ≤ S ≤ 50 000 Number of small sky lanterns.
0 ≤ x, y ≤ 2
30 Bounds for coordinates.
Note: The picture on the right illustrates the sample input below
Sample Input
8
3 4
2 8
5 4
1 8
4 7
3 10
11 2
7 3
6
5 12
3 7
3 3
4 5
0 4
2 6
Sample Output
3
##题意:
在平面上给出若干个"大点"和"小点".
求有多少个小点满足:在任一由三个大点组成的三角形的内部或边界上.
##题解:
看图很容易看出要求一个凸包(证明也很容易).
然后依次判断各点是否在凸包内或边界上.
需要注意的是:
用longlong代替double参与运算,避免精度误差.
由于数据规模的限制,判断点是否在凸多边形内时要用O(logn)的算法. 以下代码用了二分法.
##代码:
``` cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define eps 1e-8
#define double LL
#define maxn 101000
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;
struct Point{
double x,y;
Point(){}
Point(double tx,double ty) {x=tx;y=ty;}
// bool operator<(const Point& b)const
// {
// if(x==b.x) return y<b.y;
// return x<b.x;
// }
};
int sign(double x)
{
//if(fabs(x)<eps) return 0;
if(x == 0) return 0;
return x<0? -1:1;
}
double dmul(Point p0,Point p1,Point p2)
{return (p1.x-p0.x)(p2.x-p0.x)+(p1.y-p0.y)(p2.y-p0.y);}
/x>0逆时针 x<0顺时针 x=0三点共线 考虑精度/
double xmul(Point p0,Point p1,Point p2)
{return (p1.x-p0.x)(p2.y-p0.y)-(p2.x-p0.x)(p1.y-p0.y);}
/求两点间距离/
double Distance(Point p1,Point p2)
{
return sqrt((p1.x-p2.x)(p1.x-p2.x)+(p1.y-p2.y)(p1.y-p2.y));
}
int n,m;
Point points[11000];
int _stack[11000],top; /_stack保存凸包构成点,逆时针/
int cmp_with_polar(Point p1,Point p2)
{
double tmp=xmul(points[0],p1,p2);
if(sign(tmp)>0) return 1;
else if(sign(tmp)==0&&sign(Distance(points[0],p1)-Distance(points[0],p2))<0)
return 1;
else return 0;
}
void polar_sort(int n)
{
int pos=0;
Point p0;
p0.x=points[0].x;p0.y=points[0].y;
for(int i=1;i<n;i++){
if(sign(p0.y-points[i].y)>0||(sign(p0.y-points[i].y)==0&&sign(p0.x-points[i].x)>0)){
p0.x=points[i].x;
p0.y=points[i].y;
pos=i;
}
}
points[pos]=points[0];
points[0]=p0;
sort(points+1,points+n,cmp_with_polar);
}
void ConvexHull_Graham(int n) /最终凸包点为_stack[0]~_stack[top-1],共top个/
{
polar_sort(n);
top=0;
for(int i=0;i<n;i++){
while(top>1&&sign(xmul(points[_stack[top-2]],points[_stack[top-1]],points[i]))<=0) top--;
_stack[top++]=i;
}
}
double cross(Point p0, Point p1, Point p2)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
/二分法判断点是否在凸多边形内(或边界上)/
bool is_in(int index[], int n, Point p) {
int l=1, r=n-2,mid;
while(l<=r) {
mid = (l+r) >> 1;
double a1 = xmul(points[index[0]], points[index[mid]], p);
double a2 = xmul(points[index[0]], points[index[mid+1]], p);
if(sign(a1)>=0 && sign(a2)<=0) {
if(sign(xmul(points[index[mid]], points[index[mid+1]], p)) >= 0) return 1;
return 0;
} else if(sign(a1) < 0) {
r = mid -1;
} else {
l = mid+1;
}
}
return 0;
}
int main(int argc, char const *argv[])
{
//IN;
int n, m;
while(scanf("%d", &n) != EOF)
{
for(int i=0; i<n; i++) {
scanf("%I64d %I64d", &points[i].x,&points[i].y);
}
ConvexHull_Graham(n);
//for(int i=0; i<top; i++)
// printf("%I64d %I64d\n", points[_stack[i]].x, points[_stack[i]].y);
scanf("%d", &m);
int ans = 0;
while(m--) {
Point cur;
scanf("%I64d %I64d", &cur.x,&cur.y);
if(is_in(_stack, top, cur)) ans++;
}
printf("%d\n", ans);
}
return 0;
}
UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)的更多相关文章
- UVA - 13024 Saint John Festival 凸包+二分
题目链接:https://vjudge.net/problem/UVA-13024 题意:先给出\(L\)个点构造一个凸包,再给出\(S\)个点,询问有几个点在凸包内. 题解:判断点是否在凸包内的模板 ...
- Saint John Festival Gym - 101128J (凸包二分)
Problem J: Saint John Festival \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出\(n\)个大点,和\(m\ ...
- 【计算几何】【凸包】【极角排序】【二分】Gym - 101128J - Saint John Festival
平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内. 对红点求凸包后,转化为询问有多少个黑点在凸包内. 点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后 ...
- UVA 13024: Saint John Festival(凸包+二分 ,判定多个点在凸包内)
题意:给定N个点,Q次询问,问当前点知否在N个点组成的凸包内. 思路:由于是凸包,我们可以利用二分求解. 二分思路1:求得上凸包和下凸包,那么两次二分,如果点在对应上凸包的下面,对应下凸包的上面,那么 ...
- Gym 101128J Saint John Festival(凸包 + 二分判点和凸包关系)题解
题意:给你一堆黑点一堆红点,问你有最多几个黑点能找到三个红点,使这个黑点在三角形内? 思路:显然红点组成的凸包内的所有黑点都能做到.但是判断黑点和凸包的关系朴素方法使O(n^2),显然超时.那么我现在 ...
- 15-16 ICPC europe J Saint John Festival (graham扫描法+旋转卡壳)
题意:给n个大点,m个小点$(n<=1e5,m<=5e5),问有多少个小点,存在3个大点,使小点在三个大点组成的三角形内. 解题思路: 首先,易证,若该小点在某三大点行成的三角形内,则该小 ...
- UVaLive 6859 Points (几何,凸包)
题意:给定 n 个点,让你用最长的周长把它们严格包围起来,边长只能用小格子边长或者是小格子对角线. 析:先把每个点的上下左右都放到一个集合中,然后求出一个凸包,然后先边长转成题目的方式,也好转两个点的 ...
- uva109求凸包面积,判断点是不是在凸包内
自己想了一个方法判断点是不是在凸包内,先求出凸包面积,在求由点与凸包上每两个点之间的面积(点已经排好序了),如果两者相等,则点在凸包内,否则不在(时间复杂度可能有点高)但是这题能过 #include& ...
- logN判点是否在凸多边形内 HRBUSTOJ1429
就是利用叉积的性质,如果向量A1到向量A2是顺时针则叉积为负反之为正. 然后我们可以二分的判断找到一个点恰被两条射线夹在一起. 然后我们再判断是否l,r这两个点所连直线与点的关系. 具体资料可以参照这 ...
随机推荐
- Jquery的.post说解
Jquery的.post说解(一) 准备工作 ·Customer类 public class Customer { public int Unid { get; set; } pu ...
- nodejs初写心得
nodejs安装后如何查看和安装其他工具 网上nodejs的文章已经很多,这里只是写下自己的小小心得,如果能帮到别人当然更好. 安装nodejs这里就不叙述了,直接上nodejs官网下载就好了,初学者 ...
- bzoj1594
首先想到二分答案 然后我们从大往小加区间,如果之前出现了一个区间包含当前区间 那显然不合法,我们可以用并查集了维护 type node=record x,y,mi,id:longint; end; . ...
- UVa 10054 The Necklace【欧拉回路】
题意:给出n个珠子,珠子颜色分为两半,分别用1到50之间的数字表示, 现在给出n个珠子分别的颜色,问是否能够串成一个环.即为首尾相连,成为一个回路 判断是否构成一个环,即判断是否为欧拉回路,只需要判断 ...
- [ASP.NET 技术点滴] Jquery 前端验证
先上HTML代码: <form id="login" name="login" action="~/f_login/Login" me ...
- POJ 3084 Panic Room (最小割建模)
[题意]理解了半天--大意就是,有一些房间,初始时某些房间之间有一些门,并且这些门是打开的,也就是可以来回走动的,但是这些门是确切属于某个房间的,也就是说如果要锁门,则只有在那个房间里才能锁. 现在一 ...
- I.MX6 linux Qt 同时支持Touch、mouse
/***************************************************************************** * I.MX6 linux Qt 同时支持 ...
- Linux中 干掉原来的PHP方法
干掉原来的PHP方法: 查看php版本命令:#php -v这个命令是删除不干净的#yum remove php因为使用这个命令以后再用#php -v还是会看到有版本信息的..... 必须强制删除#rp ...
- 数据库语言(二):SQL语法实例整理
连接表达式: select * from student join takes on student.ID = takes.ID; 通过on后面的谓词作为连接条件,相同的属性可以出现两次,也就是等价于 ...
- Jquery获取第一个子元素
如获取id为divId的div下的第一个子div $("#divId").children("div").get(0) 但得到的是一个dom对象,如果要得到Jq ...