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)判断点在凸多边形内)的更多相关文章

  1. UVA - 13024 Saint John Festival 凸包+二分

    题目链接:https://vjudge.net/problem/UVA-13024 题意:先给出\(L\)个点构造一个凸包,再给出\(S\)个点,询问有几个点在凸包内. 题解:判断点是否在凸包内的模板 ...

  2. Saint John Festival Gym - 101128J (凸包二分)

    Problem J: Saint John Festival \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出\(n\)个大点,和\(m\ ...

  3. 【计算几何】【凸包】【极角排序】【二分】Gym - 101128J - Saint John Festival

    平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内. 对红点求凸包后,转化为询问有多少个黑点在凸包内. 点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后 ...

  4. UVA 13024: Saint John Festival(凸包+二分 ,判定多个点在凸包内)

    题意:给定N个点,Q次询问,问当前点知否在N个点组成的凸包内. 思路:由于是凸包,我们可以利用二分求解. 二分思路1:求得上凸包和下凸包,那么两次二分,如果点在对应上凸包的下面,对应下凸包的上面,那么 ...

  5. Gym 101128J Saint John Festival(凸包 + 二分判点和凸包关系)题解

    题意:给你一堆黑点一堆红点,问你有最多几个黑点能找到三个红点,使这个黑点在三角形内? 思路:显然红点组成的凸包内的所有黑点都能做到.但是判断黑点和凸包的关系朴素方法使O(n^2),显然超时.那么我现在 ...

  6. 15-16 ICPC europe J Saint John Festival (graham扫描法+旋转卡壳)

    题意:给n个大点,m个小点$(n<=1e5,m<=5e5),问有多少个小点,存在3个大点,使小点在三个大点组成的三角形内. 解题思路: 首先,易证,若该小点在某三大点行成的三角形内,则该小 ...

  7. UVaLive 6859 Points (几何,凸包)

    题意:给定 n 个点,让你用最长的周长把它们严格包围起来,边长只能用小格子边长或者是小格子对角线. 析:先把每个点的上下左右都放到一个集合中,然后求出一个凸包,然后先边长转成题目的方式,也好转两个点的 ...

  8. uva109求凸包面积,判断点是不是在凸包内

    自己想了一个方法判断点是不是在凸包内,先求出凸包面积,在求由点与凸包上每两个点之间的面积(点已经排好序了),如果两者相等,则点在凸包内,否则不在(时间复杂度可能有点高)但是这题能过 #include& ...

  9. logN判点是否在凸多边形内 HRBUSTOJ1429

    就是利用叉积的性质,如果向量A1到向量A2是顺时针则叉积为负反之为正. 然后我们可以二分的判断找到一个点恰被两条射线夹在一起. 然后我们再判断是否l,r这两个点所连直线与点的关系. 具体资料可以参照这 ...

随机推荐

  1. 自动化:Appium运行成功,取得一个小的胜利

    看过乙醇大神的博文,然后又看了一些大神的博文,自己陆陆续续的折腾了一个月,今天上午的时候,appium终于跑起来了.纪念下,在自动化路上取得的一个小胜利 Appium版本:1.2 Python版本:2 ...

  2. 分解成3NF的保持函数依赖的分解算法:

    转换成3NF的保持函数依赖的分解算法: ρ={R1<U1,F1>,R2<U2,F2>,...,Rk<Uk,Fk>}是关系模式R<U,F>的一个分解,U= ...

  3. nodejs抓网易NBA数据

    var http = require("http");var cheerio = require("cheerio"); var url = "htt ...

  4. topcoder srm 610 div2 250

    第一次做tc 的比赛,一点也不懂,虽然题目做出来了, 但是,也没有在比赛的时候提交成功.. 还有,感谢一宁对tc使用的讲解.. 贴一下代码..... #include <cstring> ...

  5. UVa 1638 (递推) Pole Arrangement

    很遗憾,这么好的一道题,自己没想出来,也许太心急了吧. 题意: 有长度为1.2.3...n的n个杆子排成一行.问从左到右看能看到l个杆子,从右往左看能看到r个杆子,有多少种排列方法. 分析: 设状态d ...

  6. Windows Azure® 由世纪互联运营发布MySQL Database on Azure正式商用版

    我们很高兴宣布MySQL Database on Azure于2015年9月1日在中国地区正式商用.回望过去,从2014年12月对少量用户开放的预览试用,到2015年4月30日对中国用户全面开放的公共 ...

  7. DataGuard相同SID物理Standby搭建

    Oracle Data Guard 是针对企业数据库的最有效和最全面的数据可用性.数据保护和灾难恢复解决方案.它提供管理.监视和自动化软件基础架构来创建和维护一个或多个同步备用数据库,从而保护数据不受 ...

  8. ftp在shell脚本中的使用方法

    1. ftp自动登录批量下载文件. #####从ftp服务器上的/home/data 到 本地的/home/databackup#####!/bin/bashftp -n<<!open 1 ...

  9. TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议

    把这三个协议放到一起学习是因为这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP得到要传输的数 ...

  10. MySQL基础之第1章 数据库概述

    1.1.数据存储方式 1.人工管理阶段2.文件系统阶段3.数据库系统阶段 1.2.数据库泛型 数据库泛型就是数据库应该遵循的规则.数据库泛型也称为范式.目前关系数据库最常用的四种范式分别是:第一范式( ...