题目:

给定平面上 n n n个点 ( x i , y i ) (x_i,y_i) (xi​,yi​),找四个点组成四边形,问组成的四边形的最大面积是多少。注意会有重点,四边形可以退化。
( 4 ≤ n ≤ 4096 , 0 ≤ x i , y i ≤ 1 0 9 ) (4 \le n \le 4096,0 \le x_i,y_i \le 10^9) (4≤n≤4096,0≤xi​,yi​≤109)

题解:

首先,能取到凸四边形肯定不会取凹四边形。
先用点集搞出凸包,如果凸包上少于三个点,那么只能退化为一条线,答案为0;如果凸包上只有三个点,而其他点都在凸包内部,所以只能组成凹四边形或者退化成三角形;如果至少有四个点,那么说明可以组成凸四边形,显然面积最大的四边形的四个点都在凸包上。考虑枚举四边形的一条对角线,那么四边形就可以看成是两个三角形拼起来的,我们使这两个三角形的面积最大即可。先看一边,考虑怎么使三角形面积最大,底边已经确定,所以我们找出一个点,到底边的距离最大即可,借鉴一下旋转卡壳的思路,由于凸包的凸性,所以一边的点到枚举的对角线的距离是一个単峰函数,所以当我们确定对角线的其中一个点,遍历枚举另一个点时,也就是对角线在绕一个点旋转时,到对角线距离最大的点也会单调的旋转,所以搞双指针维护即可。
由于给定的都是整点,而要求的是面积,所以面积或是一个整数,或是一个.5的小数。那么我们在算三角形面积的时候不除以2,最后特判整数或.5即可。实现的时候全用long long,无精度损失。

复杂度: O ( n 2 ) O(n^2) O(n2)

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<sstream>
#include<ctime>
//#include<chrono>
//#include<random>
//#include<unordered_map>
using namespace std;#define ll long long
#define ls o<<1
#define rs o<<1|1
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
const double pi=acos(-1.0);
const double eps=1e-6;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn=5005;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
struct Point{ll x,y;Point(ll x=0,ll y=0):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);
}
ll Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;
}
ll Area(Point a,Point b,Point c){return abs(Cross(b-a,c-a));
}
bool operator<(const Point &a,const Point &b){if(a.x==b.x)return a.y<b.y;else return a.x<b.x;
}
int used[maxn],stk[maxn];
int Andrew(Point *p,int n,Point *h,int *id){int tp=0;sort(p,p+n);for(int i=0;i<n;i++)used[i]=0;stk[++tp]=0;for(int i=1;i<=n-1;i++){while(tp>=2&&Cross(p[stk[tp]]-p[stk[tp-1]],p[i]-p[stk[tp]])<=0){used[stk[tp--]]=0;}used[i]=1;stk[++tp]=i;}int tmp=tp;for(int i=n-2;i>=0;i--){if(!used[i]){while(tp>tmp&&Cross(p[stk[tp]]-p[stk[tp-1]],p[i]-p[stk[tp]])<=0){used[stk[tp--]]=0;}used[i]=1;stk[++tp]=i;}}for(int i=1;i<=tp;i++){h[i-1]=p[stk[i]];id[i-1]=stk[i];}return tp-1;
}
ll RotateCalipers(Point *p,int n){ll res=0;for(int i=0;i<n;i++){int j=(i+1)%n,jj=(i+3)%n;for(int k=(i+2)%n;k!=i;k=(k+1)%n){while(Area(p[i],p[j],p[k])<Area(p[i],p[(j+1)%n],p[k]))j=(j+1)%n;while(Area(p[i],p[jj],p[k])<Area(p[i],p[(jj+1)%n],p[k]))jj=(jj+1)%n;res=max(res,Area(p[i],p[j],p[k])+Area(p[i],p[jj],p[k]));}}return res;
}
int T,n;
Point p[maxn],h[maxn];
int id[maxn];
int main(void){// freopen("in.txt","r",stdin);scanf("%d",&T);while(T--){scanf("%d",&n);for(int i=0;i<n;i++){scanf("%lld%lld",&p[i].x,&p[i].y);}int num=Andrew(p,n,h,id);if(num<3){puts("0");continue;}ll ans=0;if(num==3){for(int i=0;i<n;i++){int flag=0;for(int j=0;j<num;j++){if(i==id[j]){flag=1;break;}}if(flag)continue;ll s=Area(h[0],h[1],h[2]);ll mn=min(Area(p[i],h[1],h[2]),min(Area(h[0],p[i],h[2]),Area(h[0],h[1],p[i])));ans=max(ans,s-mn);}}else{ans=RotateCalipers(h,num);}if(ans%2==0)printf("%lld\n",ans/2);else printf("%lld.5\n",ans/2);}return 0;
}

gym102460 2019ICPC台湾L Largest Quadrilateral相关推荐

  1. Gym - 102460L Largest Quadrilateral(几何-凸包+旋转卡壳求最大的四边形面积)

    题目链接:点击查看 题目大意:在笛卡尔坐标系上给出 n 个点,要求选出四个点,使得组成的四边形面积最大,求出这个最大的面积,注意此处组成的四边形不是严格意义上的四边形,只需要选四个点就行 题目分析:首 ...

  2. MYSQL实现ORDER BY LIMIT的方法以及优先队列(堆排序)

    一.MYSQL中的LIMIT和ORACLE中的分页 在MYSQL官方文档中描述limit是在结果集中返回你需要的数据,它可以尽快的返回需要的行而不用管剩下的行, 在ORACLE中也有相关的语法比如 1 ...

  3. 数据结构与算法分析c++第四版_研分享 | 人工智能学院数据结构与算法分析考研备考整理...

    数据结构与算法分析 1.在顺序表中插入或删除一个元素,需要平均移动(表中一半)元素,具体移动的元素个数与(表长和该元素在表中的位置)有关. 2.如果有两个数,每个数的所有约数(除它本身以外)的和正好等 ...

  4. 算法导论chapter6 堆排序的代码

    按照<算法导论>上的伪代码实现了,刚开始没注意index的问题,导致错误,看来对于伪代码实现C还是要注意下啊!! #include<iostream> #include < ...

  5. 判断字符串数组中是否所有字符只出现了一次

    题目:给定一个字符类型数组chas,判断chas中是否所有的字符都只出现过一次 要求1: 时间复杂度为O(N)的算法 思路:使用哈希表,记录每个字符出现是否在哈希表里出现,如果没有出现,则添加; 若重 ...

  6. 时间复杂度为on的排序算法_排序算法amp;时间复杂度计算

    对于排序算法而言,有几个重要的点: 理解此种排序算法是怎么运行的 理解算法的时间复杂度与空间复杂度计算 递推公式(关乎时间复杂度的计算) 递推公式主要为以下的形式(递归使用的复杂度也这么算): 具体推 ...

  7. Python数据结构常见的八大排序算法(详细整理)

    前言 八大排序,三大查找是<数据结构>当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法. 常见的八大排序算法,他们之间关系如下: 排序算法.png 他们的性能比较: 下 ...

  8. c程序预处理器的设计与实现_C预处理器-能力问题与解答

    c程序预处理器的设计与实现 C programming Pre-processor Aptitude Questions and Answers: In this section you will f ...

  9. python 自动复制分类_leetcode python 常见分类问题模板(复制粘贴就能用) 更新中......

    排序 插入.希尔.冒泡.选择 def insertSort(arr): for i in range(1,len(arr)): tmp = arr[i] for j in range(i-1,-1,- ...

最新文章

  1. git pull出现There is no tracking information for the current branch
  2. 微生物组—宏基因组分析专题培训开课啦!
  3. RocketMQ高性能之底层存储设计
  4. 联想(Lenovo)小新310经典版进bios方法
  5. json 示例_JSON文件 数据格式及格式化转换
  6. 云上攻击太多怎么办?不妨试试这些工具
  7. 【IJCAI2021】长文本知识抽取:基于语义分割的文档级三元组关系抽取
  8. H.264 NAL层解析
  9. kuangbin专题-简单搜索
  10. 测试cpu是否有问题的软件,cpu测试软件|CPU检测软件有哪些 5款CPU检测工具介绍
  11. 九位SEO专家分享他们对Google核心更新的看法
  12. 微软官方原版本下载msdn
  13. 连续两次入围Gartner魔力象限的Quick BI到底有何魔力?
  14. 年轻人最in的选择!HCK哈士奇x可口可乐联名限量款冰吧
  15. android 和 js 之间交互的封装
  16. python 代码转程序_python2代码转python3
  17. 【JavaWeb学习】HTML
  18. BASE64加密解密及乱码问题
  19. 数据库连接JDBC原理
  20. 在Mysql中为什么定义varchar(255)?

热门文章

  1. 2009IT领域十大并购案回顾-思科收购腾博 HP收购3COM
  2. C# WPF 关于async/await异步用法
  3. 好用的对比工具beyondcompare
  4. Origin2022提示“应用程序无法启动(0×c000007b)解决方案
  5. 【Linux基础】Windows10安装Ubuntu20.04双系统
  6. 使用小程序实现识别图像文字并提取
  7. 27.Python数据库操作(一)【内置数据库SQLite和ORM框架SQLAlchemy】
  8. BS1064-基于大数据存储实现互联网电子商城网站及数据分析系统
  9. 香港理工大学计算机科学教授,新闻详情 - 计算机科学与工程系 - 南方科技大学...
  10. Smartbi开发之--默认打开主题下的某分析