POJ 2079 求最大三角形面积 (凸包+旋转卡壳)
2014-03-28 16:50
423 查看
题目链接:http://poj.org/problem?id=2079
方法:凸包+旋转卡壳(O(n^2))
[cpp] view
plaincopyprint?
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 50000
using namespace std;
//定义点
struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};
typedef Point Vector;
Point p[N+10];
Point ch[N+10];
const double eps = 1e-10;
int dcmp(double x)
{
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
//点-点=向量
Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);}
double Cross(Vector A, Vector B){return A.x*B.y - A.y*B.x;}
bool cmp ( Point a, Point b )
{
if ( a.x != b.x ) return a.x < b.x;
else return a.y < b.y;
}
int ConvexHull(Point ch[], int n, Point p[])
{
sort(p, p+n, cmp);
int m = 0;
//下凸边
for(int i = 0; i < n; i++)
{
while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;
ch[m++] = p[i];
}
int k = m;
//上凸边
for(int i = n-2; i >= 0; i--)
{
while(m > k && dcmp(Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])) <= 0) m--;
ch[m++] = p[i];
}
if(n > 1) m--;
return m;
}
double rotaing_calipers(Point ch[], int n)
{
int p;
int i, j;
double ans = 0;
for( i = 0; i < n-1; i++)
{
p = 1;
for( j = i+1; j < n; j++)
{
while(fabs(Cross(ch[j]-ch[i],ch[p+1]-ch[i])) > fabs((Cross(ch[j]-ch[i],ch[p]-ch[i]))))
p = (p+1) % (n-1);
ans = max(ans, fabs(Cross(ch[i]-ch[p],ch[j]-ch[p])));
}
ans = max(ans, fabs(Cross(ch[i]-ch[p],ch[j]-ch[p])));
}
return ans/2;
}
int main ()
{
// freopen("a.txt","r", stdin);
int n;
while(scanf("%d", &n) != EOF)
{
if(n == -1) break;
for(int i = 0; i < n; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
int len = ConvexHull(ch, n, p);
double ans = rotaing_calipers(ch, len);
printf("%.2f\n", ans);
}
return 0;
}
方法:凸包+旋转卡壳(O(n^2))
[cpp] view
plaincopyprint?
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 50000
using namespace std;
//定义点
struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) {}
};
typedef Point Vector;
Point p[N+10];
Point ch[N+10];
const double eps = 1e-10;
int dcmp(double x)
{
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
//点-点=向量
Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);}
double Cross(Vector A, Vector B){return A.x*B.y - A.y*B.x;}
bool cmp ( Point a, Point b )
{
if ( a.x != b.x ) return a.x < b.x;
else return a.y < b.y;
}
int ConvexHull(Point ch[], int n, Point p[])
{
sort(p, p+n, cmp);
int m = 0;
//下凸边
for(int i = 0; i < n; i++)
{
while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;
ch[m++] = p[i];
}
int k = m;
//上凸边
for(int i = n-2; i >= 0; i--)
{
while(m > k && dcmp(Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])) <= 0) m--;
ch[m++] = p[i];
}
if(n > 1) m--;
return m;
}
double rotaing_calipers(Point ch[], int n)
{
int p;
int i, j;
double ans = 0;
for( i = 0; i < n-1; i++)
{
p = 1;
for( j = i+1; j < n; j++)
{
while(fabs(Cross(ch[j]-ch[i],ch[p+1]-ch[i])) > fabs((Cross(ch[j]-ch[i],ch[p]-ch[i]))))
p = (p+1) % (n-1);
ans = max(ans, fabs(Cross(ch[i]-ch[p],ch[j]-ch[p])));
}
ans = max(ans, fabs(Cross(ch[i]-ch[p],ch[j]-ch[p])));
}
return ans/2;
}
int main ()
{
// freopen("a.txt","r", stdin);
int n;
while(scanf("%d", &n) != EOF)
{
if(n == -1) break;
for(int i = 0; i < n; i++)
scanf("%lf %lf", &p[i].x, &p[i].y);
int len = ConvexHull(ch, n, p);
double ans = rotaing_calipers(ch, len);
printf("%.2f\n", ans);
}
return 0;
}
相关文章推荐
- POJ 2079 Triangle(凸包+旋转卡壳,求最大三角形面积)
- POJ 2079 Triangle(凸包_旋转卡壳之最大三角形面积)
- POJ 2079 Triangle(凸包+旋转卡壳求最大三角形面积)
- POJ 2079 Triangle(凸包+旋转卡壳,求最大三角形面积)
- poj 2079 Triangle 凸包+旋转卡壳 求最大三角形面积
- hdu 3934&&poj 2079 (凸包+旋转卡壳+求最大三角形面积)
- poj 2079(旋转卡壳求解凸包内最大三角形面积)
- POJ 2079 Triangle (平面点最大三角形 凸包+旋转卡壳 推荐)
- POJ 2079 Triangle(旋转卡壳计算平面点集最大三角形面积)
- POJ 2079 Triangle (凸包中的最大三角形&旋转卡壳)
- poj2079 Triangle (旋转卡壳之最大三角形)
- 强大的旋转卡壳 POJ 2187 最远点对 POJ 2079点集中面积最大的三角形
- poj2079凸包求最大三角形面积
- poj 2079 Triangle,旋转卡壳求点集的最大三角形
- ZOJ 2419-- Triangle-凸包+旋转卡壳求最大面积三角形(计算几何)
- HDOJ 2202 最大三角形 凸包旋转卡壳求最大三角形面积
- poj 2079 Triangle,旋转卡壳求点集的最大三角形
- POJ 2079 求最大三角形面积
- [BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳
- BZOJ 1069: [SCOI2007]最大土地面积 凸包,旋转卡壳