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这两个点所连直线与点的关系. 具体资料可以参照这 ...
随机推荐
- HDU 4675 GCD of Sequence(容斥)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4675 题意:给出n,m,K,一个长度为n的数列A(1<=A[i]<=m).对于d(1< ...
- VS2015中快捷注释代码块
注释ctrl+k ctrl+c 反注释ctrl+k ctrl+u 需要注意的是第二个ctrl不能省略的
- 转载:Unobtrusive JavaScript in ASP.NET MVC 3 隐式的脚本在MVC3
Unobtrusive JavaScript 是什么? <!--以下是常规Javascript下写出来的Ajax--> <div id="test"> &l ...
- UVA 11806 Cheerleaders (容斥原理)
题意 一个n*m的区域内,放k个啦啦队员,第一行,最后一行,第一列,最后一列一定要放,一共有多少种方法. 思路 设A1表示第一行放,A2表示最后一行放,A3表示第一列放,A4表示最后一列放,则要求|A ...
- hdu 1211 RSA
// 表示题目意思我是理解了蛮久 英语太水了 //首先这是解密公式 m=c^d mod n// 给你 p q e 然后 n=p*q fn=(p-1)*(q-1)// 给你 e,根据公式 e*d mod ...
- Mysql线程池优化笔记
Mysql线程池优化我是总结了一个站长的3篇文章了,这里我整理到一起来本文章就分为三个优化段了,下面一起来看看. Mysql线程池系列一(Thread pool FAQ) 首先介绍什么是mys ...
- 【转】Intel HEX介绍
记录格式 Intel HEX由任意数量的十六进制记录组成.每个记录包含5个域,它们按以下格式排列: :llaaaatt[dd...]cc 每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数 ...
- equals(),hashcode()方法详解
Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals ...
- Activity与Activity之间,Fragment与Fragment之间通过Bundle传值的研究
一.Fragment与Activity的通讯 在使用fragment的时候,通常的用法都是使用一个activity来管理不同的fragment,所以每个fragment与activity的及时通讯 ...
- Android中获取应用程序(包)的信息----PackageManager
本节内容是如何获取Android系统中应用程序的信息,主要包括packagename.label.icon.占用大小等.具体分为两个 部分,计划如下: 第一部分: 获取应用程序的packagena ...