poj 2187 Beauty Contest——旋转卡壳

题目:http://poj.org/problem?id=2187

学习材料:https://blog.csdn.net/wang_heng199/article/details/74477738

     https://www.jianshu.com/p/74c25c0772d6

可以再倒着枚举一遍那样求凸包。

用叉积算面积来旋转卡壳。

注意在面积等于的时候就不要往后走了,不然只有两个点的数据就会死循环。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define db double
using namespace std;
const int N=5e4+5;
int n,sta[N],top,ans;
struct Node{
  int x,y;
  Node(int a=0,int b=0):x(a),y(b) {}
  bool operator< (const Node &b)const
  {return x<b.x||(x==b.x&&y<b.y);}
  Node operator- (const Node &b)const
  {return Node(x-b.x,y-b.y);}
}t[N],a[N];
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)fx=0;ch=getchar();}
  while(ch>=‘0‘&&ch<=‘9‘)ret=ret*10+ch-‘0‘,ch=getchar();
  return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int cross(Node u,Node v){return u.x*v.y-u.y*v.x;}
int Sqr(int x){return x*x;}
int dist(Node u,Node v){return Sqr(u.x-v.x)+Sqr(u.y-v.y);}
void rtc()
{
  a[n+1]=a[1];
  for(int i=1,p=2;i<=n;i++)
    {
      while(cross(a[p+1]-a[i],a[p+1]-a[i+1])>cross(a[p]-a[i],a[p]-a[i+1]))//>
    {p++;if(p>n)p=1;}//for if only 2 ver!!!
      ans=Mx(ans,Mx(dist(a[p],a[i]),dist(a[p+1],a[i+1])));
      //      ans=Mx(ans,Mx(dist(a[p],a[i+1]),dist(a[p-1],a[i])));
    }
}
int main()
{
  int tot=rdn();
  for(int i=1;i<=tot;i++)t[i].x=rdn(),t[i].y=rdn();
  sort(t+1,t+tot+1);
  for(int i=1;i<=tot;i++)
    {
      while(top>1&&cross(t[i]-t[sta[top]],t[i]-t[sta[top-1]])>=0)top--;
      sta[++top]=i;
    }
  for(int i=tot-1,lm=top;i;i--)
    {
      while(top>lm&&cross(t[i]-t[sta[top]],t[i]-t[sta[top-1]])>=0)top--;///top>lm
      sta[++top]=i;
    }
  n=top-1;
  for(int i=1;i<=n;i++)a[i]=t[sta[i]];
  rtc(); printf("%d\n",ans);
  return 0;
}

原文地址:https://www.cnblogs.com/Narh/p/10145014.html

时间: 2024-07-29 17:40:44

poj 2187 Beauty Contest——旋转卡壳的相关文章

POJ 2187 Beauty Contest

题意: 题目链接 给定 \(n\) 个点,求距离最远的两个点之间的距离,输出最远距离的平方 \(n<=50000\) 思路: 旋转卡壳... 注意事项: 数组名称不要弄混了 code: #include<cstdio> #include<algorithm> using namespace std; const int N=50005; int n,top,per[N],res; struct point{int x,y;int dist(){return x*x+y*y;}

poj 2079 Triangle,旋转卡壳求点集的最大三角形

给出一个点集,求顶点在点集中的最大的三角形面积. 我们知道这三角形的三个点肯定在凸包上,我们求出凸包之后不能枚举,因为题目n比较大,枚举的话要O(n^3)的数量级,所以采用旋转卡壳的做法: 首先枚举三角形的第一个顶点i, 初始化第二个顶点j=i+1和第三个顶点k=j+1,对k进行循环,直到找到第一个k使得cross(i,j,k)>cross(i,j,k+1),如果k==i进入下一次循环. 对j,k进行旋转,每次循环之前更新最大值,然后固定一个j,同样找到一个k使得cross(i,j,k)>cr

hdu 3934&amp;&amp;poj 2079 (凸包+旋转卡壳+求最大三角形面积)

链接:http://poj.org/problem?id=2079 Triangle Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 8173   Accepted: 2423 Description Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices

poj 2079 Triangle 凸包+旋转卡壳

题意: 给平面上n个点,求这n个点组成的最大三角形面积. 分析: 旋转卡壳,但要注意和求平面最远点对的区别,最大三角形的边不一定在凸包上的,也贴出以前写的求平面最远点对的poj 2187代码作为对比. 代码: //poj 2079 //sep9 #include <iostream> #include <algorithm> using namespace std; const int maxN=50012; struct P { int x,y; }pnt[maxN],cnt[m

poj 2079 Triangle(旋转卡壳)

Triangle Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 8917   Accepted: 2650 Description Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points. Input

POJ 2187 旋转卡壳 + 水平序 Graham 扫描算法

水平序 Graham 扫描算法: 计算二维凸包的时候可以用到,Graham 扫描算法有水平序和极角序两种. 极角序算法能一次确定整个凸包, 但是计算极角需要用到三角函数,速度较慢,精度较差,特殊情况较多. 水平序算法需要扫描两次,但排序简单,讨论简单,不易出错. [算法流程] 1.对顶点按x为第一关键字,y为第二关键字进行排序. 2.准备一个空栈,并将前两个点压入栈. 3.对于每一个顶点A,只要栈顶中还至少两个顶点,记栈顶为T,栈中第二个为U. 若UT(向量) * TA(向量) <= 0, 则将

【POJ 2187】 Beauty Contest (凸包-Graham扫描算法)

[POJ 2187] Beauty Contest (凸包-Graham扫描算法) 找平面最远点对 数据很大 用暴力会T..我感觉-- 扫描出个凸包 然后枚举凸包上的点即可 没坑 int也可过 注意重边跟共线就行 代码下附赠几组数据 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include

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

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

POJ2187 Beauty Contest(旋转卡壳)

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