Gym - 101201E:Enclosure (点到凸包的切线)
题意:给点N棵树,前K棵是已经拥有的,现在可以再拥有一棵树,问形成的最大凸包面积。
思路:先求K棵树的凸包C,然后对于后面的N-K棵树,我们先判断是否在凸包内,如果不在,我们要求两个切线。 这里分类讨论,即可。
如果点在C的左边,那么两条切线分别一上一下; 如果在下边,两条切线一左一右。 然后去对应区间二分即可。
(好像还有双指针的线性做法:求两个凸包,维护两条切线即可。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
struct point{
ll x,y;
point(){}
point(ll xx,ll yy):x(xx),y(yy){}
};
bool cmp(point w,point v){
if(w.x!=v.x) return w.x<v.x;
return w.y<v.y;
}
ll det(point a,point b){ return a.x*b.y-a.y*b.x;}
ll dot(point a,point b){ return a.x*b.x+a.y*b.y;}
point operator +(point a,point b){ return point(a.x+b.x,a.y+b.y);}
point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);}
point a[maxn],ch[maxn]; int top,ttop;
void convexhull(int N)
{
for(int i=;i<=N;i++){
while(top>&&det(ch[top]-ch[top-],a[i]-ch[top-])<=) top--;
ch[++top]=a[i];
}
ttop=top;
for(int i=N-;i>=;i--){
while(top>ttop&&det(ch[top]-ch[top-],a[i]-ch[top-])<=) top--;
ch[++top]=a[i];
}
}
int get(int L,int R,int i,int w)
{
while(L<R){
int Mid=(L+R)>>;
if(det(ch[Mid]-a[i],ch[Mid+]-a[i])*w>) R=Mid;
else L=Mid+;
}
return L;
}
int bord(int L,int R,int i,int w)
{
while(L<R){
int Mid=(L+R)>>;
if((ch[Mid].x-a[i].x)*w<) L=Mid+;
else R=Mid;
}
return L;
}
ll ans,sum[maxn],tmp;
int main()
{
int N,K;
scanf("%d%d",&N,&K);
rep(i,,N) scanf("%lld%lld",&a[i].x,&a[i].y);
sort(a+,a+K+,cmp); convexhull(K);
rep(i,,top-) ans+=det(ch[i],ch[i+]),sum[i+]=ans;
rep(i,K+,N){
if(a[i].x<ch[].x){
int L=get(,ttop,i,),R=get(ttop,top,i,-);
tmp=sum[R]-sum[L]+det(ch[R],a[i])+det(a[i],ch[L]);
}
else if(a[i].x>ch[ttop].x){
int L=get(,ttop,i,-),R=get(ttop,top,i,);
tmp=sum[top]-sum[R]+sum[L]+det(ch[L],a[i])+det(a[i],ch[R]);
}
else if(det(ch[ttop]-a[],a[i]-ch[])>){//shang
int Mid=bord(ttop,top,i,-);
if(Mid>ttop&&det(ch[Mid]-ch[Mid-],a[i]-ch[Mid-])>) continue;
int L=Mid>ttop?get(ttop,Mid-,i,-):Mid;
int R=get(Mid,top,i,);
tmp=sum[top]-sum[R]+sum[L]+det(ch[L],a[i])+det(a[i],ch[R]);
}
else {
int Mid=bord(,ttop,i,);
if(Mid>&&det(ch[Mid]-ch[Mid-],a[i]-ch[Mid-])>) continue;
int L=Mid>?get(,Mid-,i,-):;
int R=get(Mid,ttop,i,);
tmp=sum[top]-sum[R]+sum[L]+det(ch[L],a[i])+det(a[i],ch[R]);
}
ans=max(ans,tmp);
}
printf("%lld.%lld\n",ans/,ans%*);
return ;
}
/*
5 3
-5 -5
-5 5
5 -5
-4 6
5 5
*/
Gym - 101201E:Enclosure (点到凸包的切线)的更多相关文章
- Gym 101606B - Breaking Biscuits - [凸包+旋转卡壳][凸包的宽度]
题目链接:https://codeforces.com/gym/101606/problem/B 题解: 对于给出的 $n$ 个点,先求这些点的凸包,然后用旋转卡壳求出凸包的宽度(Width (min ...
- [codeforces/gym/101350/L]维护“凸包”
题目链接:http://codeforces.com/gym/101350/problems 给定n个墙,每个墙有一个高度,要支持动态修改墙的高度和查询这个“容器”能盛多少水. (队友)观察发现,能盛 ...
- poj1375Intervals(点到圆的切线)
链接 貌似这样的叫解析几何 重点如何求得过光源到圆的切线与地板的交点x坐标,可以通过角度及距离来算,如图, 根据距离和半径可以求得角度a.b.r,自然也可以求得d1,d2. 至于方向问题,在求r得时候 ...
- UVA 11168 - Airport - [凸包基础题]
题目链接:https://cn.vjudge.net/problem/UVA-11168 题意: 给出平面上的n个点,求一条直线,使得所有的点在该直线的同一侧(可以在该直线上),并且所有点到该直线的距 ...
- 【计算几何】【分类讨论】Gym - 101173C - Convex Contour
注意等边三角形的上顶点是卡不到边界上的. 于是整个凸包分成三部分:左边的连续的三角形.中间的.右边的连续的三角形. 套个计算几何板子求个三角形顶点到圆的切线.三角形顶点到正方形左上角距离啥的就行了,分 ...
- HDU 4667 Building Fence(求凸包的周长)
A - Building Fence Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u ...
- 【BZOJ3203】[Sdoi2013]保护出题人 二分+凸包
[BZOJ3203][Sdoi2013]保护出题人 Description Input 第一行两个空格隔开的正整数n和d,分别表示关数和相邻僵尸间的距离.接下来n行每行两个空格隔开的正整数,第i + ...
- hdu4266(三维凸包模板题)
/*给出三维空间中的n个顶点,求解由这n个顶点构成的凸包表面的多边形个数. 增量法求解:首先任选4个点形成的一个四面体,然后每次新加一个点,分两种情况: 1> 在凸包内,则可以跳过 2> ...
- opencv::凸包-Convex Hull
概念介绍 什么是凸包(Convex Hull),在一个多变形边缘或者内部任意两个点的连线都包含在多边形边界或者内部. 正式定义:包含点集合S中所有点的最小凸多边形称为凸包 Graham扫描算法 首先选 ...
随机推荐
- 03:open-falcon报警定制
1.1 配置报警 11111111111111111111
- 剑指offer(51)构建乘积数组
题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...
- flask --- 04 . 偏函数, 线程安全,栈堆,
一.偏函数(partial) ①第一种 结果为: ② 第二种 二.线程安全 将空间转换成时间 问题: 1秒钟打印所有结果 threading.current_thread().ident :线程ID ...
- FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解
Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...
- Java 成员变量和属性的区别
例一: 一个Student pojo类: public class Student{ private String name; private int age; public String getNa ...
- zookeeper之 zkServer.sh命令、zkCli.sh命令、四字命令
一.zkServer.sh 1.查看 zkServer.sh 帮助信息[root@bigdata05 bin]# ./zkServer.sh helpZooKeeper JMX enabled by ...
- 《温故而知新》JAVA基础一
一:基本环境 种类 javaSE(核心语法)+javaME(移动设备)+Java EE(JSP/服务等) JVM(java虚拟机) abc.java(源文件)--编译器--abc.class 字节码文 ...
- java笔记 -- GregorianCalendar和DateFormateSymbols 类方法
java.util.GregorianCalendar new GregorianCalendar() 构造一个日历对象, 用于表示默认地区,默认时区的当前时间. new GregorianCalen ...
- 基于虹软的Android的人脸识别SDK使用测试
现在有很多人脸识别的技术我们可以拿来使用:但是个人认为还是离线端的SDK比较实用:所以个人一直在搜集人脸识别的SDK:原来使用开源的OpenCV:最近有个好友推荐虹软的ArcFace, 闲来无事就下来 ...
- Pyhon中运算符的使用
1. a & b python中的&延续了C/C++的含义,表示位运算. 例如 3 & 4:3&5:6&7 3 & 4 = (011)2 & ( ...