Problem J: Saint John Festival

\[Time Limit: 1 s \quad Memory Limit: 256 MiB
\]

题意

给出\(n\)个大点,和\(m\)个小点,然后问有多少个小点可以在任意一个\(3\)个大点组成的三角形内。

思路

很明显只要对大点求凸包,然后判断有多少个在凸包里的小点就可以了,但是判断点在凸包内如果用\(O(N)\)的方法会\(TLE\),需要进行二分。

我求出的是逆时针的凸包,然后定下一个端点\(p[1]\),寻找另外两个端点\(p[id]\)和\(p[id+1]\),根据查询的点在\(p[1]-p[id]\)这条直线右侧或者在\(p[1]-p[id+1]\)这个点左侧来二分范围,如果在\(p[1]-p[id]\)和\(p[1]-p[id+1]\)之间,那么在判断是否在\(p[id]-p[id+1]\)左侧来判断是否在凸包内。

/***************************************************************
> File Name : J.cpp
> Author : Jiaaaaaaaqi
> Created Time : 2019年05月06日 星期一 18时14分21秒
***************************************************************/ #include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 5e4 + 10;
const int maxm = 1e5 + 10;
const ll mod = 1e9 + 7;
const ll INF = 1e18 + 100;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-8;
using namespace std; int n, m;
int cas, tol, T;
int sgn(double x) {
if(fabs(x) <= eps) return 0;
else return x>0 ? 1 : -1;
}
struct Point {
double x, y;
Point() {}
inline Point(double _x, double _y) {
x = _x, y = _y;
}
inline Point operator - (Point a) const {
return Point(x-a.x, y-a.y);
}
inline double operator ^ (Point a) const {
return x*a.y - y*a.x;
}
inline double distance(Point p) const {
return hypot(x-p.x, y-p.y);
}
inline bool operator < (Point a) const {
return sgn(y-a.y)==0 ? sgn(x-a.x)<0 : y<a.y;
}
inline bool operator == (Point a) const {
return sgn(x-a.x)==0 && sgn(y-a.y)==0;
}
inline double operator * (Point a) const {
return x*a.x + y*a.y;
}
};
struct Line {
Point s, e;
Line() {}
Line(Point _s, Point _e) {
s = _s, e = _e;
}
inline bool pointseg(Point p) {
return sgn((p-s)^(e-s)) == 0 && sgn((p-s)*(p-e)) <=0;
}
};
struct Polygon {
int n;
Point p[maxn];
Line l[maxn];
inline void add(Point q) {
p[++n] = q;
}
struct cmp {
Point p;
cmp(Point _p) {
p = _p;
}
bool operator() (Point _a, Point _b) const {
Point a = _a, b = _b;
int d = sgn((a-p)^(b-p));
if(d == 0) {
return sgn(a.distance(p) - b.distance(p)) < 0;
} else {
return d>0;
}
}
};
void norm() {
int id = 1;
for(int i=2; i<=n; ++i) {
if(p[i] < p[id])
id = i;
}
swap(p[id], p[1]);
sort(p+1, p+1+n, cmp(p[1]));
}
void Graham(Polygon &convex) {
norm();
mes(convex.p, 0);
int &top = convex.n = 0;
if(n == 1) {
convex.p[++top] = p[1];
} else if(n == 2) {
convex.p[++top] = p[1];
convex.p[++top] = p[2];
if(convex.p[1] == convex.p[2]) top--;
} else {
convex.p[++top] = p[1];
convex.p[++top] = p[2];
for(int i=3; i<=n; ++i) {
while(top>1 && sgn((convex.p[top]-convex.p[top-1])^
(p[i]-convex.p[top-1])) <= 0)
top--;
convex.p[++top] = p[i];
}
if(top == 2 && convex.p[1] == convex.p[2])
top--;
}
}
void getline() {
for(int i=1; i<=n; ++i) {
l[i] = Line(p[i], p[i%n+1]);
}
}
int inconvex(Point s) {
/*
点和凸包的关系
2 边上
1 内部
0 外部
*/
Point p1 = p[1];
Line l1 = Line(p[1], p[2]);
Line l2 = Line(p[1], p[n]);
if(l1.pointseg(s) || l2.pointseg(s))
return 2;
int l = 2, r = n-1;
while(l<=r) {
int mid = l+r>>1;
int t1 = sgn((s-p1)^(p[mid]-p1));
int t2 = sgn((s-p1)^(p[mid+1]-p1));
if(t1 <= 0 && t2 >= 0) {
int t3 = sgn((s-p[mid]) ^ (p[mid+1]-p[mid]));
if(t3 < 0) return 1;
else if(t3 == 0) return 2;
return 0;
}
if(t1 > 0) r = mid-1;
else l = mid+1;
}
return 0;
}
} large, small, con;
inline int read() {
int x = 0, f = 1;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')f = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
x = x * 10 + s - '0';
s = getchar();
}
return x * f;
}
int main() {
n = read();
large.n = small.n = con.n = 0;
int x, y;
for(int i=1; i<=n; ++i) {
x = read(), y =read();
large.add(Point(1.0*x, 1.0*y));
}
m = read();
for(int i=1; i<=m; ++i) {
x = read(), y =read();
small.add(Point(1.0*x, 1.0*y));
}
large.norm();
large.Graham(con);
int ans = 0;
for(int i=1; i<=m; ++i) {
if(con.inconvex(small.p[i])) {
ans++;
}
}
printf("%d\n", ans);
return 0;
}

Saint John Festival Gym - 101128J (凸包二分)的更多相关文章

  1. UVALive 7281 Saint John Festival (凸包+O(logn)判断点在凸多边形内)

    Saint John Festival 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/J Description Porto's ...

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

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

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

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

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

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

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

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

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

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

  7. 【bzoj3203】[Sdoi2013]保护出题人 凸包+二分

    题目描述 输入 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + 1行为Ai和 Xi,分别表示相比上一关在僵尸队列排头增加血量为Ai 点的 ...

  8. 【bzoj2402】陶陶的难题II 分数规划+树链剖分+线段树+STL-vector+凸包+二分

    题目描述 输入 第一行包含一个正整数N,表示树中结点的个数.第二行包含N个正实数,第i个数表示xi (1<=xi<=10^5).第三行包含N个正实数,第i个数表示yi (1<=yi& ...

  9. UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP

    [NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...

随机推荐

  1. 破解Charles4.2.7版本

    软件下载地址:请点我 密码:sats dmg软件解密密码是:xclient.info 激活方法 1.将 Charles.app 拖至 应用程序 文件夹 2.将 keygen.jar 拖至 桌面 3.打 ...

  2. 【题解】Luogu P2992 [USACO10OPEN]三角形计数Triangle Counting

    原题传送门 我们考虑进行容斥 包含原点的三角形个数=所有可能三角形的个数-不包含原点三角形的个数 对于每个点,我们会发现:将它与原点连线,在直线左边任选两点或右边任选两点与这个点构成的三角形一定是不包 ...

  3. Go语言入门——hello world

    Go 语言源代码文件扩展名是.go. 知识点:1. go语言代码的第1行必须声明包2. 入口的go语言代码(包含main函数的代码文件)的包必须是main,否则运行go程序会显示go run: can ...

  4. VS代码调试出现:当前不会命中断点。还没有为该文档加载任何符号。

    第一步:一定要检查最顶部自己设置的是 Release模式还是Debug模式!!!下面这个图就是在我搜了好多解决方式之后,突然发现自己开的是Release模式!!!吐血. 第二步:如果你已经确定了自己是 ...

  5. dotnet core系列之Background tasks with hosted services (后台任务)

    这篇简单讲asp.net core 中的后台任务 用到的包: Microsoft.AspNetCore.App metapackage 或者加入 Microsoft.Extensions.Hostin ...

  6. C#中如何禁止WindowsMediaPlayer双击全屏显示

    问题描述:在项目中使用WindowsMediaPlayer播放视频时,双击会出现视频全屏的效果,而且视频恢复后会暂停,除非再次双击返回后才能正常播放.那么如何禁止WindowsMediaPlayer的 ...

  7. xml文件操作帮助类

    xml文件的节点值获取和节点值设置 /// <summary> /// 保存单个点节点的值 /// </summary> /// <param name="Up ...

  8. 2019 东方网java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.东方网等公司offer,岗位是Java后端开发,因为发展原因最终选择去了东方网,入职一年时间了,也成为了面试官 ...

  9. 【MySQL】mysql中的锁机制

    一.分类 MySQL的锁机制不同的存储引擎支持不同的锁机制,分为表级锁.行级锁.页面锁.MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking):BDB存储引擎采用的 ...

  10. 原生JS实现前端动画框架

    封装了一个JS方法,可支持块元素的常规动画:高.宽.透明度.位置等,同时支持链式动画和同时运动,参照imooc整理,具体代码如下: /** * 获取HTML元素属性值 * obj是Element, a ...