【旋转卡壳】poj 2187 Beauty Contest
来源:互联网 发布:贵金属交易软件排行 编辑:程序博客网 时间:2024/05/16 14:06
Link:poj.org/problem?id=2187
旋转卡壳(求平面最远对(O(N)))
先求出其凸包,找凸包所有边的与其他点最大三角形,其点即为边的最远点,
再计算边两端点的与边的最远点距离,取下最大距离。
当我们逆时针枚举边的时候,最远点的变化也是逆时针的,这样就可以不用从头计算最远点,
而可以紧接着上一次的最远点继续计算。于是我们得到了O(n)的算法。
#include <cstdio>#include <cmath>#include <algorithm>using namespace std;/*poj 2187题意:给你一些点,找最远的两点题解:旋转卡壳*/const int N = 50010;const double PI = acos(-1.0);struct Point{ double x,y;};bool cmp(Point aa,Point bb){ if(aa.y != bb.y) return aa.y < bb.y; return aa.x < bb.x;} //是否严格左转,共线不算(叉乘) //计算三角形面积(叉乘)double xmult(Point a,Point b,Point c) //(ca)×(cb){ return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);}Point a[N];int n,cnt,tail;int tmp[N],ans[N];void Graham(){ sort(a,a+n,cmp);// for(int i = 0; i < n; i++)// printf("%d %f %f\n",i,a[i].x,a[i].y); cnt = tail = 0; tmp[tail++] = 0; tmp[tail++] = 1; for(int i = 2; i < n; i++) { while(tail>1 && xmult(a[tmp[tail-1]],a[i],a[tmp[tail-2]])<=0) //是否严格左转 tail--; tmp[tail++] = i; } for(int i = 0; i < tail; i++) ans[cnt++] = tmp[i]; tail = 0; tmp[tail++] = n-1; tmp[tail++] = n-2; for(int i = n-3; i >= 0; i--) { while(tail>1 && xmult(a[tmp[tail-1]],a[i],a[tmp[tail-2]])<=0) //是否严格左转 tail--; tmp[tail++] = i; } cnt--; //去掉重复的点 for(int i = 0; i < tail; i++) ans[cnt++] = tmp[i];// for(int i = 0; i < cnt; i++)// printf("%d ",ans[i]);// puts("");}double dist(Point p1,Point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));}int dist2(Point p1,Point p2){ return (int)(p1.x-p2.x)*(p1.x-p2.x) + (int)(p1.y-p2.y)*(p1.y-p2.y);}int rotating_calipers() //旋转卡壳{ int q=1; //处理到的点 int res = 0; for(int i = 0; i < cnt-1; i++){ while(xmult(a[ans[q+1]],a[ans[i]],a[ans[i+1]]) > xmult(a[ans[q]],a[ans[i]],a[ans[i+1]])) //三角形面积 q = (q+1)%(cnt-1); res = max(res,max(dist2(a[ans[i]],a[ans[q]]),dist2(a[ans[i+1]],a[ans[q]])));// printf("%d %d %d\n",ans[i],ans[i+1],q); } return res;}int main(){ while(~scanf("%d",&n)) { for(int i = 0; i < n; i++) scanf("%lf%lf",&a[i].x,&a[i].y); Graham(); printf("%d\n",rotating_calipers()); } return 0;}
阅读全文
0 0
- Poj 2187 Beauty Contest(旋转卡壳)
- poj 2187 Beauty Contest(旋转卡壳)
- POJ 2187: Beauty Contest(旋转卡壳)
- POJ 2187 Beauty Contest(旋转卡壳)
- POJ 2187 Beauty Contest 旋转卡壳
- POJ 2187 Beauty Contest 旋转卡壳
- [POJ 2187]Beauty Contest(旋转卡壳)
- POJ 2187 Beauty Contest(旋转卡壳)
- POJ 2187Beauty Contest旋转卡壳
- POJ 2187 Beauty Contest 旋转卡壳
- [POJ 2187]Beauty Contest:旋转卡壳
- 【旋转卡壳】poj 2187 Beauty Contest
- POJ:2187 Beauty Contest 旋转卡壳
- poj 2187 Beauty Contest(凸包+旋转卡壳)
- POJ 2187 Beauty Contest(凸包+旋转卡壳)
- POJ 2187 Beauty Contest [凸包,旋转卡壳]
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
- POJ 2187 Beauty Contest(旋转卡壳求点凸包直径)
- Super Jumping! Jumping! Jumping! --DP
- linux编程---进程通信中,利用socketpair实现子进程间通信
- WebRTC实时通信系列教程6 使用RTCDataChannel传输数据
- 解决PopupWindow在7.0以上位置不正确的bug
- 代码 框架学习系列 mybatis 第八篇 mybatis开发dao的方式
- 【旋转卡壳】poj 2187 Beauty Contest
- 日历控件
- B
- 安卓常用方法和布局总结
- 启动hdfs后,一个datanode缺失
- Proxygen编译安装和开发环境的搭建
- layer iframe层的使用,传参
- json-server+mockjs 模拟REST接口
- [FAQ03426]android 4.4当系统存在多个Launcher时,如何设 置开机自动进入默认的Launcher?