#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
struct pointt
{
double x, y;
};
pointt operator-(pointt a, pointt b)
{
pointt c;
c.x = a.x - b.x; c.y = a.y - b.y;
return c;
}
pointt operator+ (pointt a, pointt b)
{
pointt c;
c.x = a.x + b.x; c.y = a.y + b.y;
return c;
}
double dot(pointt a, pointt b)
{
return a.x*b.y - b.x*a.y;
}
struct linee
{
pointt p1, vec;
linee(pointt a, pointt b) :p1(a), vec(b - a)
{}
linee()
{}
};
pointt point[4000], tubao[4000];
int n;
double ans = 0;
bool isonleft(pointt test, linee std)
{
double t = dot(test - std.p1, std.vec);
return t <= 0;
}
double dist(pointt a, pointt b)
{
double kk = (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
kk = sqrt(kk);
return kk;
}
bool com(pointt a, pointt b)
{
double t = dot(a - point[0], b - point[0]);
if (t == 0)
{
return dist(a, point[0]) < dist(b, point[0]);
}
return t > 0;
return false;
}
int last = 1;
void graham()
{
sort(point + 1, point + 1 + n, com);
//for (int i = 1; i <= n; i++)
//cout << "x:" << point[i].x << " " << "y:" << point[i].y << endl;
tubao[0] = point[1]; tubao[1] = point[2];
for (int i = 3; i <= n; i++)
{
while (last >= 1 && isonleft(tubao[last], linee(tubao[last - 1], point[i])))last--;
tubao[++last] = point[i];
}
last++;//注意这是一定要last++的不然会有大麻烦因为mod运算在电脑里的就是坑啊....负数取摸还是负数,蓝后实际上是有last+1个数的所以要last++
for (int i = 0; i < last; i++)
{
int first =i+1; int second = i+3;
for (int j = i + 2; j <last-1; j++)//注意这里是%(last+1)容易错!!!!还有mod后是有负数的所以专门写个函数解决这个问题
{
while (abs(dot(tubao[i] - tubao[(first + 1)%last], tubao[j] - tubao[(first + 1)%last])) >
fabs(dot(tubao[i] - tubao[first], tubao[j] - tubao[first]))){
first = (first + 1)%last;
}
while (fabs(dot(tubao[i] - tubao[(second+1)%last], tubao[j] - tubao[(second+1)%last])) >
fabs(dot(tubao[i] - tubao[second], tubao[j] - tubao[second]))){
second = (second + 1)%last;
}
ans = max(ans, fabs(dot(tubao[i] - tubao[second], tubao[j] - tubao[second])) +
fabs(dot(tubao[i] - tubao[first], tubao[j] - tubao[first])));
}
}
ans /= 2;
}
int main()
{
scanf("%d", &n);
pointt min;
min.x = 1000000000; min.y = 1000000000;
for (int i = 1; i <= n; i++)
{
double a, b;
scanf("%lf%lf", &a, &b);
point[i].x = a; point[i].y = b;
if (b < min.y || ((b == min.y) && a < min.x))min = point[i];
}
point[0] = min;
graham();
printf("%.3lf\n", ans);
return 0;
}
凸包应用——旋转卡壳bzoj1069
最新推荐文章于 2024-03-16 22:42:58 发布