【模板】 旋转卡壳 poj2187

题目链接:https://vjudge.net/problem/POJ-2187

旋转卡壳模板题。参考了hzwer(http://hzwer.com/4224.html)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #define eps 1e-8
 6 using namespace std;
 7 int n,top;
 8 const int N = 5e4+9;
 9 int sta[N];
10 struct Point{
11     double x,y;
12     Point operator - (const Point& b)const{
13         return (Point){x-b.x,y-b.y};
14     }
15     double operator ^ (const Point& b)const{
16         return x*b.y - b.x*y;
17     }
18 }p[N],p0;
19 bool cmp(Point a,Point b){
20     if(atan2(a.y - p0.y,a.x - p0.x) != atan2(b.y - p0.y,b.x - p0.x)){
21         return atan2(a.y - p0.y,a.x - p0.x) < atan2(b.y - p0.y,b.x - p0.x);
22     }
23     return a.x < b.x;
24 }
25 double dis2(Point a,Point b){
26     return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
27 }
28 void init(){
29     int k=0;
30     scanf("%lf %lf",&p[0].x,&p[0].y);
31 //    cin>>p[0].x>>p[0].y;
32     p0 = p[0];
33     for(int i = 1;i<n;++i){
34         scanf("%lf %lf",&p[i].x,&p[i].y);
35 //        cin>>p[i].x>>p[i].y;
36         if( (p0.y > p[i].y) || (p0.y == p[i].y && p0.x > p[i].x)){
37             p0 = p[i];
38             k = i;
39         }
40     }
41     p[k] = p[0];
42     p[0] = p0;
43     sort(p+1,p+n,cmp);
44 }
45 void graham(){
46     if(n == 2){
47         top = 1;
48         sta[0] = 0;
49         sta[1] = 1;
50         return;
51     }
52     sta[0] = 0; sta[1] = 1; top = 1;
53     for(int i = 2;i<n;++i){
54         while( top>0 && ( (p[sta[top]] - p[sta[top-1]]) ^ (p[i]-p[sta[top-1]]) ) <= 0 ) --top;
55         sta[++top] = i;
56     }
57 }
58 void RC(){
59     sta[top+1] = sta[0];
60     int now = 1;
61     double ans = 0;
62     for(int i = 0;i<=top;++i){
63         while( ((p[sta[i+1]]-p[sta[i]])^(p[sta[now]] - p[sta[i]])) < ((p[sta[i+1]]-p[sta[i]])^(p[sta[now+1]]-p[sta[i]])) ){
64             ++now;
65             if(now == top+1) now = 0;
66         }
67         ans = max(ans,max(dis2(p[sta[i]],p[sta[now]]),dis2(p[sta[i+1]],p[sta[now]])));
68     }
69     printf("%d\n",(int)ans);
70 }
71 int main(){
72     scanf("%d",&n);
73     init();
74     graham();
75     RC();
76     return 0;
77 }

原文地址:https://www.cnblogs.com/xiaobuxie/p/11622679.html

时间: 2024-12-13 06:53:09

【模板】 旋转卡壳 poj2187的相关文章

模板 旋转卡壳 凸包

模板 旋转卡壳 凸包 好早以前看的,现在再记下来吧,当做复习一遍. 那么,先提一下最基本最暴力的求凸包直径的方法吧---枚举...好吧..很多问题都可以用 枚举 这个“万能”的方法来解决,过程很简单方便是肯定的,不过在效率上就要差很远了.  要求一个点集的直径,即使先计算出这个点集的凸包,然后再枚举凸包上的点对,这样来求点集直径的话依然会在凸包上点的数量达到O(n)级别是极大的降低它的效率,也浪费了凸包的优美性质.不过在数据量较小或者很适合时,何必要大费周折的用那些麻烦复杂的算法呢,枚举依然是解

模板 凸包 旋转卡壳

模板  凸包  旋转卡壳 lrj <训练指南> P272 对于个点按照 x 从小到大排序,再按照 y 点从小到大排序,删除重复的点后,得到序列 p0,p1,p2..., 把 p0 和 p1 放入凸包. 从p2开始,当新点在凸包“前进”方向的左边时继续,否则依次删除最近加入凸包的点,直到新点在左边 PS:判断用叉积即可 1 /******************************************** 2 计算凸包,输入点数组 p, 个数为 n , 输出点数组 ch. 函数返回凸包顶

POJ2187 Beauty Contest (旋转卡壳算法 求直径)

POJ2187 旋转卡壳算法如图 证明:对于直径AB 必然有某一时刻 A和B同时被卡住 所以旋转卡壳卡住的点集中必然存在直径 而卡壳过程显然是O(n)的 故可在O(n)时间内求出直径 凸包具有良好的性质 其中的点是有序的 对于某个点 从它之后的点与它的距离必然是一个单峰凸函数 根据这个性质也可以设计一个O(nlogn)的算法 给出代码 #include<iostream> #include<stdio.h> #include<stdlib.h> #include<

旋转卡壳部分模板

凸包直径 旋转卡壳凸包直径详解 //计算凸包直径,输入凸包ch,顶点个数为n,按逆时针排列,输出直径的平方 int rotating_calipers(int n) { int q = 1; int ans = 0; ch[n] = ch[0]; for(int i = 0 ; i < n; i++) { while(mul(ch[i+1],ch[q+1],ch[i])>mul(ch[i+1],ch[q],ch[i]))//枚举凸包一条边并扫描其它点,通过计算三角形面积的方法找到最远的点 q

算法复习——凸包加旋转卡壳(poj2187)

题目: Description Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'Miss Cow World'. As a result, Bessie will make a tour of N (2 <= N <= 50,000) farms around the world in order to spread goodwill

[POJ2187][BZOJ1069]旋转卡壳

旋转卡壳 到现在依然不确定要怎么读... 以最远点对问题为例,枚举凸包上的两个点是最简单的想法,时间复杂度O(n2) 我们想象用两条平行线卡着这个凸包,当其中一个向某个方向旋转的时候另一个显然也是朝同样的方向旋转 所以在枚举其中一条边的过程中完全没有必要重新枚举另一条边 而且对于一条边而言,凸包上的点到这条边的距离是满足单峰性质的 所以线性的做法就出来啦 ↓代码非常短很优秀~ procedure Roatating_Calipers; begin stack[len+1]:=stack[1];j

POJ2187 Beauty Contest(旋转卡壳)

嘟嘟嘟 旋转卡壳模板题. 首先求出凸包. 然后\(O(n ^ 2)\)的算法很好想,但那就不叫旋转卡壳了. 考虑优化:直观的想是在枚举点的时候,对于第二层循环用二分或者三分优化,但实际上两点距离是不满足单调性的,见下图: 对于\(A\)点,\(AB < AC < AD > AE < AF\). 那怎么办呢? 转换一下思路,如果枚举边,会发现每一个不在这条边上的顶点到边的距离是一个单峰函数!因此就能想到三分这个点,复杂度变成\(O(nlogn)\). 不过实际上还可以优化,如果逆时针

[模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

//to update 一些基本的定义在这里: [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算 自适应Simpson 凸包 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){retu

【模板】旋转卡壳求 面积最大的三角形 poj2079

题目链接:https://vjudge.net/problem/POJ-2079 graham跑的巨慢,Andrew跑的巨快.还好写. 有两种写法. 旋转卡壳枚举三个点的(94ms) 1 /************************************************************************* 2 > File Name: poj2079.cpp 3 # File Name: poj2079.cpp 4 # Author : xiaobuxie 5 #