叉积 Cross(vec a,vec b) a = p0p1 b = p0p2 如果p2在p0p1的左边,叉积为正
//1.每次新加入的点一定在前进方向的左边,不在的话,就将原来的点删去,直至在左边为止
hdu1348 求凸包周长 + 2 * pi * l
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1000 + 5;
const double pi = acos(-1.0);
struct point{
double x,y;
bool operator < (const point &a) const{
return x < a.x || (x == a.x && y < a.y);
}
point operator - (const point &a) const{
return point{x - a.x,y - a.y};
}
}ps[maxn],ans[maxn];
typedef point vec;
double Cross(vec a,vec b){
return a.x * b.y - a.y * b.x;
}
int ConvexHull(point ps[],int n,point ans[])
{
sort(ps,ps + n);
int m = 0;
for(int i = 0;i < n;i ++){
while(m > 1 && Cross(ans[m - 1] - ans[m - 2],ps[i] - ans[m - 2]) < 0) m --;//还是会有一条线段上多个点
ans[m ++] = ps[i];
}
//刚好逆时针
for (int i = n - 2; i >= 0; i --) {
while(m > 1 && Cross(ans[m - 1] - ans[m - 2],ps[i] - ans[m - 2]) < 0) m --;
ans[m ++] = ps[i];
}
if(n > 1) m --;
return m;
}
double getdis(point &a,point &b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main()
{
int T;scanf("%d",&T);
int n,l;
for(int cn = 0;cn < T;cn ++){
scanf("%d%d",&n,&l);
for (int i = 0; i < n; i ++) {
scanf("%lf%lf",&ps[i].x,&ps[i].y);
}
int sz = ConvexHull(ps, n, ans);
double res = getdis(ans[0], ans[sz - 1]);
for (int i = 0; i < sz - 1; i ++) {
res += getdis(ans[i], ans[i + 1]);
}
res += 2 * pi * l;
if(cn) printf("\n");
printf("%.0lf\n",res);
}
return 0;
}
//2 分治,给定直线,每次找距离直线最远的点,该点一定在凸包上
poj3348 求凸包面积
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e4 + 5;
struct point{
double x,y;
bool operator < (const point &a) const{
return x < a.x || (x == a.x && y < a.y);
}
point operator - (const point &a) const{
return point{x - a.x,y - a.y};
}
}ps[maxn];
int ans[maxn];
int num = 0;
typedef point vec;
double Corss(vec a,vec b){
return a.x * b.y - a.y * b.x;
}
bool up[maxn],down[maxn];
double f(point &a,point &b,point &c)
{
return a.x * b.y + c.x * a.y + b.x * c.y - c.x * b.y - b.x * a.y - a.x * c.y;
}
void ConvexHullUp(int l,int r,bool vis[])
{
int area = 0,id = -1;
for (int i = l + 1; i < r; i ++) {
double t = f(ps[l], ps[r], ps[i]);
if(t > area){
area = t;
id = i;
}
}
if(area > 0){
vis[id] = 1;
ConvexHullUp(l, id, vis);
ConvexHullUp(id, r, vis);
}
}
void ConvexHullDown(int l,int r,bool vis[])
{
int area = 0,id = -1;
for (int i = l + 1; i < r; i ++) {
double t = f(ps[l], ps[r], ps[i]);
if(t < area){
area = t;
id = i;
}
}
if(area < 0){
vis[id] = 1;
ConvexHullDown(l, id, vis);
ConvexHullDown(id, r, vis);
}
}
double getdis(point &a,point &b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double getarea(point &p1,point &p2,point &p3){
double a = getdis(p1, p2);
double b = getdis(p1, p3);
double c = getdis(p2, p3);
double p = (a + b + c) / 2;
return sqrt(p * (p - a) * (p - b) * (p - c));
}
int main()
{
int n;scanf("%d",&n);
for (int i = 0; i < n; i ++) {
scanf("%lf%lf",&ps[i].x,&ps[i].y);
}
sort(ps,ps + n);
up[0] = up[n - 1] = 1;
down[0] = down[n - 1] = 1;
ConvexHullUp(0,n - 1,up);
ConvexHullDown(0, n - 1, down);
for (int i = 0; i < n; i ++) {
if(down[i]) ans[num ++] = i;
}
for (int i = n - 2; i > 0; i --) {
if(up[i]) ans[num ++] = i;
}
double sum = 0;
for (int i = 0; i < num - 2; i ++) {
sum += getarea(ps[ans[i]],ps[ans[i + 1]],ps[ans[num - 1]]);
}
printf("%d\n",(int)floor(sum / 50));
return 0;
}