Time Limit: 3000MS | Memory Limit: 30000K | |
Total Submissions: 9060 | Accepted: 2698 |
Description
Input
Output
Sample Input
3
3 4
2 6
2 7
5
2 6
3 9
2 0
8 0
6 5
-1
Sample Output
0.50
27.00
Source
旋转卡壳算法可以参见我的上一篇博客以及里面的链接:http://www.cnblogs.com/liyinggang/p/5431908.html
题意:求解平面中的点中任意取三个能够形成最大的三角形面积。
题解:先用凸包把所有可能的点选出来,最大三角形必定是由凸包上的三点形成。
我们枚举底边,于是我们可以的到以下两种情况:
1.此三角形的底边在凸包上,求得次边对应的最远的点(不是对踵点),由于凸包是个单峰函数,所以只要找到第一个这个点比上一个点
大就找到了。记录下此时的面积(对应黄色线条).
2.如果三角形底边不再凸包上,我们利用同样的方法找到离此底边最远的点(对应红色线条)
aaarticlea/png;base64,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" alt="" width="183" height="207" />1,2相比,取大值
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; const int N = ;
struct Point{
int x,y;
}p[N],Stack[N];
int n; int mult(Point a,Point b,Point c){
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
int dis(Point a,Point b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int cmp(Point a,Point b){
if(mult(a,b,p[])>) return ;
if(mult(a,b,p[])==&&dis(b,p[])>dis(a,p[])) return ;
return ;
}
int Graham(){
sort(p+,p+n,cmp);
int top = ;
Stack[]=p[];
Stack[]=p[];
Stack[]=p[];
for(int i=;i<n;i++){
while(top>=&&mult(p[i],Stack[top],Stack[top-])>=){
top--;
}
Stack[++top]=p[i];
}
return top;
}
double rotating_calipers(int top){
int p=,q=; ///初始化
double ans = ;
Stack[++top]=Stack[];
for(int i = ;i<top;i++){
while(mult(Stack[i],Stack[p],Stack[q+])>mult(Stack[i],Stack[p],Stack[q])){
q= (q+)%top; ///定点i,p,q,先I,p固定,让q旋转找到最大的面积三角形,还是利用了凸包的单峰函数
}
ans = max(ans,mult(Stack[i],Stack[p],Stack[q])/2.0);
while(mult(Stack[i],Stack[p+],Stack[q])>mult(Stack[i],Stack[p],Stack[q])){
p=(p+)%top; ///i,q固定,p旋转,找到最大的三角形面积,比较记录.
}
ans = max(ans,mult(Stack[i],Stack[p],Stack[q])/2.0);
}
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF,n!=-){
for(int i=;i<n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
}
int k = ;
for(int i=;i<n;i++){
if(p[k].y>p[i].y||(p[k].y==p[i].y)&&(p[k].x>p[i].x)){
k=i;
}
}
swap(p[],p[k]);
int top = Graham();
double ans =rotating_calipers(top);
printf("%.2lf\n",ans);
}
return ;
}