UVA - 13024 Saint John Festival 凸包+二分
题目链接:https://vjudge.net/problem/UVA-13024
题意:先给出\(L\)个点构造一个凸包,再给出\(S\)个点,询问有几个点在凸包内。
题解:判断点是否在凸包内的模板题。最暴力的想法是\(o(n^2)\)枚举每个点,但实际上我们可以使用二分优化。具体操作就是以凸包最左侧点为起点,对每个点按斜率排序,然后把凸包分割成数个三角形,在这些三角形中二分查找斜率。复杂度便优化为\(o(nlogn)\)如下图。

- 在凸包\(ABCDEFG\)中可二分查找\(H\),\(I\),\(J\),\(K\)点
完成二分后,通过叉积判断点是否在凸包内,如下图。

- \(\vec{FH}\times{\vec {HE}} < 0\),\(\vec{FK}\times{\vec {KE}} > 0\)
即叉积<0则在凸包内,>0在凸包外,同时还有叉积=0的情况(点在凸包的边上)。但是叉积=0时还应考虑一种情况,即在凸包一条边的延长线上,需要特判。如下图。

- 如图所示的\(L\)点和\(M\)点叉积均为0。
AC代码:
#include <bits/stdc++.h>
#define SIZE 100007
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
typedef long long ll;
void io() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
ll n, m, t, num;
struct Point {
ll x, y;
double k;
friend bool operator<(const Point& a, const Point& b) { //为使用lower_bound进行运算符重载
return a.k <= b.k;
}
};
Point p[SIZE], ch[SIZE], tp[SIZE];
bool cmp(Point a, Point b) { //andrew算法排序预处理函数
if (a.x == b.x) return a.y < b.y;
else return a.x < b.x;
}
ll cross(Point a, Point b, Point c) { return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); }
ll crossx(Point a, Point b, Point c) { return (a.x - b.x) * (c.y - a.y) - (a.y - b.y) * (c.x - a.x); }
ll andrew() { //采用安德鲁算法求凸包,返回顶点数
sort(p + 1, p + n + 1, cmp);
ll top = 0;
for (int i = 1; i <= n; ++i) {
while ((top > 1) && (cross(ch[top - 1], ch[top], p[i]) <= 0)) --top;
ch[++top] = p[i];
}
ll tmp = top;
for (int i = n - 1; i; --i) {
while ((top > tmp) && (cross(ch[top - 1], ch[top], p[i]) <= 0)) --top;
ch[++top] = p[i];
}
if (n > 1) top--;
return top;
}
bool InConvexHull(ll top, Point x) { //判断点x是否在凸包内
ll pos = lower_bound(ch + 1, ch + top + 1, x) - ch - 1; //二分查找
if (pos == 1) return false;
ll j = crossx(x, ch[pos], ch[pos + 1]);
if (j < 0) return true;
else if (j == 0) { //叉积为0时特判
ll minx = min(ch[pos].x, ch[pos + 1].x), maxx = max(ch[pos].x, ch[pos + 1].x);
ll miny = min(ch[pos].y, ch[pos + 1].y), maxy = max(ch[pos].y, ch[pos + 1].y);
if ((minx <= x.x) && (maxx >= x.x) && (miny <= x.y) && (maxy >= x.y)) return true;
else return false;
}
else return false;
}
int main() {
io();
while (cin >> n && n) { //多组输入
num = 0;
rep(i, 1, n) cin >> p[i].x >> p[i].y;
cin >> m;
ll top = andrew();
ll x = ch[1].x, y = ch[1].y;
rep(i, 2, top) { //计算斜率
double tx = ch[i].x - x, ty = ch[i].y - y;
if (!tx) { //若x坐标相同,则斜率设为1e18
if (ty < 0) ch[i].k = -1e18;
else ch[i].k = 1e18;
}
else ch[i].k = 1.0 * ty / tx;
}
ch[1].k = -1e18;
rep(i, 1, m) {
cin >> tp[i].x >> tp[i].y;
if (ch[1].x > tp[i].x) continue;
ll tx = tp[i].x - x, ty = tp[i].y - y;
Point x;
if (!tx) {
if (ty < 0) x.k = -1e18;
else x.k = 1e18;
}
else x.k = 1.0 * ty / tx;
x.x = tp[i].x, x.y = tp[i].y;
if (InConvexHull(top, x)) ++num; //计数
}
cout << num << endl;
}
}
UVA - 13024 Saint John Festival 凸包+二分的更多相关文章
- UVA 13024: Saint John Festival(凸包+二分 ,判定多个点在凸包内)
题意:给定N个点,Q次询问,问当前点知否在N个点组成的凸包内. 思路:由于是凸包,我们可以利用二分求解. 二分思路1:求得上凸包和下凸包,那么两次二分,如果点在对应上凸包的下面,对应下凸包的上面,那么 ...
- Saint John Festival Gym - 101128J (凸包二分)
Problem J: Saint John Festival \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出\(n\)个大点,和\(m\ ...
- UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)
Saint John Festival 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/J Description Porto's ...
- Gym 101128J Saint John Festival(凸包 + 二分判点和凸包关系)题解
题意:给你一堆黑点一堆红点,问你有最多几个黑点能找到三个红点,使这个黑点在三角形内? 思路:显然红点组成的凸包内的所有黑点都能做到.但是判断黑点和凸包的关系朴素方法使O(n^2),显然超时.那么我现在 ...
- 【计算几何】【凸包】【极角排序】【二分】Gym - 101128J - Saint John Festival
平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内. 对红点求凸包后,转化为询问有多少个黑点在凸包内. 点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后 ...
- 15-16 ICPC europe J Saint John Festival (graham扫描法+旋转卡壳)
题意:给n个大点,m个小点$(n<=1e5,m<=5e5),问有多少个小点,存在3个大点,使小点在三个大点组成的三角形内. 解题思路: 首先,易证,若该小点在某三大点行成的三角形内,则该小 ...
- 【bzoj3203】[Sdoi2013]保护出题人 凸包+二分
题目描述 输入 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai 点的 ...
- 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分
题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...
- 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束)
layout: post title: 训练指南 UVA - 11478(最短路BellmanFord+ 二分+ 差分约束) author: "luowentaoaa" catal ...
随机推荐
- mysql(3):锁和事务
MySQL锁的介绍 锁是数据库系统区别于文件系统的一个关键特性.锁机制用于管理对共享资源的并发访问. 表级锁 例如MyISAM引擎,其锁是表锁设计.并发情况下的读没有问题,但是并发插入时的性能要差一些 ...
- javascript fp demo
function eq (y) { return function forX(x) { return x === y } } function mod (y) { return function fo ...
- DVWA全级别之CSRF(跨站请求伪造)
CSRF(Cross-site request forgery) CSRF,全称Cross-site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息( ...
- OPGL+VS2017+GLFW+GLEW配置详细步骤
OPGL+VS2017+GLFW+GLEW配置详细步骤: https://blog.csdn.net/weixin_40921421/article/details/80211813 原博客地址:ht ...
- 并发之ATOMIC原子操作--Unsafe解析(三)
Atomic 类的原子操作是依赖java中的魔法类sun.misc.Unsafe来实现的,而这个类为我们提供了访问底层的机制,这种机制仅供java核心类库使用,而不应该被普通用户使用. 获取Unsaf ...
- Bootstrap入门(2)表格
Bootstrap入门(四)表格 <table>标签 首先,引入bootstrap的css文件,然后表格内容放在一个class为table的<table>标签中(class=& ...
- Hadoop中的java基本类型的序列化封装类
Hadoop将很多Writable类归入org.apache.hadoop.io包中,在这些类中,比较重要的有Java基本类.Text.Writable集合.ObjectWritable等,重点介绍J ...
- Codeforces 1204D2. Kirk and a Binary String (hard version) (dp思路)
题目链接:http://codeforces.com/contest/1204/problem/D2 题目是给定一个01字符串,让你尽可能多地改变1变为0,但是要保证新的字符串,对任意的L,R使得Sl ...
- git上传时出现ERROR: Repository not found.的解决办法
今天在上传时出现错误,原因是之前更改了gitee上的个人空间地址,导致找不到.需要重新配置 https://gitee.com/help/articles/4114#article-header0
- 多对多三种创建方式、forms组件、cookies与session
多对多三种创建方式.forms组件.cookies与session 一.多对多三种创建方式 1.全自动 # 优势:不需要你手动创建第三张表 # 不足:由于第三张表不是你手动创建的,也就意味着第三张表字 ...