[模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和
一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算
自适应Simpson
Simpson's Rule:
\]
这是对二次函数的积分估值, 对于一, 二次函数来说都是准确的.
但是对于其他函数来说, 这只是利用二次函数进行近似.
可以采用自适应精度的手段, 使得估值接近真实结果. 详见代码.
然后这是误差估计, 详见 adaptive.pdf:
\]
一种实现:
db f(db x){
//returns f(x)
}
db simp(db l,db r){
db mid=(l+r)/2.0;
return (r-l)*(f(l)+4*f(mid)+f(r))/6.0;
}
db asr(db l,db r,db ans){
db mid=(l+r)/2.0;
db vl=simp(l,mid),vr=simp(mid,r),tmp=vl+vr-ans;
if(fabs(tmp)<=eps)return ans;
else return asr(l,mid,vl)+asr(mid,r,vr);
}
凸包
Andrew 算法, 即分别求上, 下凸包. 时间复杂度 \(O(n \log n)\).
struct tvec{db x,y;};
il int dcmp(db a){return fabs(a)<=eps?0:(a>0?1:-1);}
il db p2(db a){return a*a;}
il db gougu1(db a,db b){return sqrt(p2(a)+p2(b));}
il tvec operator+(tvec a,tvec b){return (tvec){a.x+b.x,a.y+b.y};}
il tvec operator-(tvec a,tvec b){return (tvec){a.x-b.x,a.y-b.y};}
il tvec operator*(tvec a,db b){return (tvec){a.x*b,a.y*b};}
il tvec operator*(db a,tvec b){return b*a;}
il db operator*(tvec a,tvec b){return a.x*b.y-b.x*a.y;}
il db operator^(tvec a,tvec b){return a.x*b.x+a.y*b.y;}
il db len(tvec a){return gougu1(a.x,a.y);}
bool cmp(tvec a,tvec b){int tmp=dcmp(a.x-b.x);return tmp?tmp<0:dcmp(a.y-b.y)<0;}
tvec li[nsz],conv[nsz];
int pc=0;
void getconv(){
sort(li+1,li+n+1,cmp);
rep(i,1,n){
while(pc>1&&dcmp((conv[pc]-conv[pc-1])*(li[i]-conv[pc]))<=0)--pc;
conv[++pc]=li[i];
}
int tmp=pc;
repdo(i,n-1,1){
while(pc>tmp&&dcmp((conv[pc]-conv[pc-1])*(li[i]-conv[pc]))<=0)--pc;
conv[++pc]=li[i];
}
if(n>1)--pc;
}
半平面交
增量法, 时间复杂度 \(O(n \log n)\) (排序的复杂度).
需要保证不是开放的半平面. 否则加上四个 \(\pm \infty\) 的平面即可.
细节较多. 详见代码...
const int psz=550;
const db eps=1e-9;
int n,m;
db dcmp(db v){return fabs(v)<=eps?0:(v>0?1:-1);}
db p2(db v){return v*v;}
struct tvec{db x,y;};
tvec operator+(tvec a,tvec b){return (tvec){a.x+b.x,a.y+b.y};}
tvec operator-(tvec a,tvec b){return (tvec){a.x-b.x,a.y-b.y};}
tvec operator*(tvec a,db b){return (tvec){a.x*b,a.y*b};}
tvec operator*(db a,tvec b){return b*a;}
db operator*(tvec a,tvec b){return a.x*b.y-a.y*b.x;}
db operator^(tvec a,tvec b){return a.x*b.x+a.y*b.y;}
db len(tvec a){return sqrt(p2(a.x)+p2(a.y));}
struct tl{
tvec p,v;
db d;
tl(){}
tl(tvec a,tvec b):p(a),v(b-a){d=atan2(v.y,v.x);}
}li[psz];
int pl=0;
bool operator<(tl a,tl b){return a.d<b.d;}
bool isleft(tl a,tvec b){return dcmp(a.v*(b-a.p))>0;}
il tvec inters(tl a,tl b){db v=(b.v*(a.p-b.p))/(a.v*b.v);return a.p+a.v*v;}
tvec poly[psz];
int ppo=0;
tl que[psz]; //queue
tvec qp[psz]; //intersect points
int qh=1,qt=0;
int hplane(){//0 fail, 1 success
sort(li+1,li+pl+1);
int pl1=1;//suppose that pl>=1
rep(i,2,pl){
if(li[i].d>li[pl1].d)li[++pl1]=li[i];
else if(isleft(li[pl1],li[i].p))li[pl1]=li[i];
}
pl=pl1;
qh=1,qt=0;
rep(i,1,pl){
while(qh<qt&&!isleft(li[i],qp[qt-1]))--qt;
while(qh<qt&&!isleft(li[i],qp[qh]))++qh;
que[++qt]=li[i];
if(qh<qt)qp[qt-1]=inters(que[qt-1],que[qt]);
}
while(qh<qt&&!isleft(que[qh],qp[qt-1]))--qt; //**
ppo=0;
if(qt-qh<=1)return 0; //no sol
qp[qt]=inters(que[qh],que[qt]);
rep(i,qh,qt)poly[++ppo]=qp[i];
return 1;
}
旋转卡壳
这是一种拥有 \(4\) 个多音字, \(2^4 = 16\) 种读音的优秀算法.
闵可夫斯基和
[模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和的更多相关文章
- HDU 6617 Enveloping Convex(凸包+半平面交+二分)
首先对于这m个点维护出一个凸包M,那么问题就变成了判断凸包P进行放大缩小能不能包含凸包M.(凸包P可以进行中心对称变换再进行放大缩小,见题意) 如何判断合适的相似比呢,我们可以用二分去放大缩小凸包P的 ...
- 【POJ 2187】Beauty Contest(凸包直径、旋转卡壳)
给定点集的最远两点的距离. 先用graham求凸包.旋(xuán)转(zhuàn)卡(qiǎ)壳(ké)求凸包直径. ps:旋转卡壳算法的典型运用 http://blog.csdn.net/hanch ...
- [Bzoj1069][Scoi2007]最大土地面积(凸包)(旋转卡壳)
1069: [SCOI2007]最大土地面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3629 Solved: 1432[Submit][Sta ...
- CSU 1806 Toll 自适应simpson积分+最短路
分析:根据这个题学了一发自适应simpson积分(原来积分还可以这么求),然后就是套模板了 学习自适应simpson积分:http://blog.csdn.net/greatwall1995/arti ...
- 【BZOJ 1069】【SCOI 2007】最大土地面积 凸包+旋转卡壳
因为凸壳上对踵点的单调性所以旋转卡壳线性绕一圈就可以啦啦啦--- 先求凸包,然后旋转卡壳记录$sum1$和$sum2$,最后统计答案就可以了 #include<cmath> #includ ...
- UVA 4728 Squares(凸包+旋转卡壳)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17267 [思路] 凸包+旋转卡壳 求出凸包,用旋转卡壳算出凸包的直 ...
- 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖
1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 1945 Solve ...
- BZOJ 1185 [HNOI2007]最小矩形覆盖:凸包 + 旋转卡壳
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1185 题意: 给出二维平面上的n个点,问你将所有点覆盖的最小矩形面积. 题解: 先找出凸 ...
- HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015年百度之星程序设计大赛 - 初赛(1)
题目链接 题意:给出n个矩形,求能覆盖所有矩形的最小的矩形的面积. 题解:对所有点求凸包,然后旋转卡壳,对没一条边求该边的最左最右和最上的三个点. 利用叉积面积求高,利用点积的性质求最左右点和长度 ...
随机推荐
- Oracle-DDL 2- 视图&索引
DDL-数据定义语句: 二.视图 --视图(view),本身不保存数据,保存的是一个查询语句--对视图的操作等同于对查询语句中源数据的操作--视图占用存储空间较小,可以快速的对特定数据进行访问和操作- ...
- Java代码执行顺序及多态体现
/** * Description: * 基类的引用变量可以只想基类的实例对象也可指向其子类的事来对象 * 接口的引用变量也可以指向实现类的实例对象 * 程序调用的方法在运行期才动态绑定 * 绑定指将 ...
- 面试40-一个数组,有2个数字出现奇数次,其余都是偶数次,求这两个数字O(n) O(1)
#include<iostream> using namespace std; // 题目:数组中只有不多于两个数字出现次数是奇数次,其他都是偶数次,求出出现奇数次的数字(不含0的数组) ...
- myeclipse显示db-brower
myeclipse显示db-brower 这东西怎么调出来? windows->show view->other->db borwser
- 打印指针要用%p而不要用%x
注意: 打印指针要用%p而不要用%x 原因: https://boredzo.org/blog/archives/2007-01-23/please-do-not-use-percent-x-for- ...
- 常用CSS代码大全(工作必备)
用html+css可以很方便的进行网页的排版布局,但不是每一种属性或者代码我们都铭记于心,最近我把CSS中的常用代码进行了归纳总结,方便自己以后查看,同时也分享给大家,希望对你们有用. 一.文本设置 ...
- 移动端H5开发自适应技巧
移动端H5开发,必要要做到自适应各种分辨率的手机,下面由我为大家大致说一下,需要3步走 第一:head标签中添加: <meta name="viewport" content ...
- python之BeautifulSoup4
阅读目录 1.Beautiful Soup4的安装配置 2.BeautifulSoup的基本用法 (1)节点选择器(tag) (2)方法选择器 (3)CSS选择器 (4)tag修改方法 Beautif ...
- linux创建定时任务发送钉钉通知
一.现在钉钉里面添加机器人 添加成功后,复制出Webhook链接. 注意,自定义关键字时你的发送信息中一定要完整包含关键字 二.找到自己的服务器 1. sudo su 切换到root用户 2.cron ...
- python 写入JSON中文乱码解决方法
在将一个字典添加入json中时多加入一个参数就可以了 json.dumps(dict(item), ensure_ascii=False) 例子 with open('zh-cn.json','w', ...