卧薪尝胆,厚积薄发。
SHOI2012 信用卡凸包
Date: Sun Dec 02 19:39:04 CST 2018 In Category: NoCategory

Description:

求圆角矩形的凸包。
$1\leqslant n\leqslant 10^4$

Solution:

发现其实就是把矩形的所有边往里缩半径那么长,然后求凸包,最后加上一个圆的周长就行了。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
int n;
double a,b,r;
#define MAXN 10010
struct point
{
double x,y;
}p[MAXN * 4];
bool cmp_x(point a,point b){return a.x < b.x;}
bool equal(double a,double b){return fabs(a - b) < 1e-9;}
int tot = 0;
point rotate(point k,double th)
{
point res;
res.x = k.x * cos(th) - k.y * sin(th);
res.y = k.x * sin(th) + k.y * cos(th);
return res;
}
point us[MAXN * 4],ds[MAXN * 4];
int utop = 0,dtop = 0;
double slope(point a,point b){return (b.y - a.y) / (b.x - a.x);}
double dis(point a,point b){return sqrt((b.y - a.y) * (b.y - a.y) + (b.x - a.x) * (b.x - a.x));}
int main()
{
scanf("%d",&n);
scanf("%lf%lf%lf",&a,&b,&r);
a = a / 2 - r;b = b / 2 - r;
double x,y,th;
for(int i = 1;i <= n;++i)
{
scanf("%lf%lf%lf",&x,&y,&th);
p[++tot] = rotate((point){b,a},th);p[tot].x += x;p[tot].y += y;
p[++tot] = rotate((point){-b,a},th);p[tot].x += x;p[tot].y += y;
p[++tot] = rotate((point){b,-a},th);p[tot].x += x;p[tot].y += y;
p[++tot] = rotate((point){-b,-a},th);p[tot].x += x;p[tot].y += y;
}
sort(p + 1,p + 1 + tot,cmp_x);
for(int i = 1;i <= tot;++i)
{
if(utop >= 1 && equal(us[utop].x,p[i].x))
{
if(p[i].y > us[utop].y)--utop;
else continue;
}
if(utop <= 1)us[++utop] = p[i];
else
{
while(utop >= 2 && slope(p[i],us[utop]) >= slope(us[utop],us[utop - 1]))--utop;
us[++utop] = p[i];
}
}
for(int i = 1;i <= tot;++i)
{
if(dtop >= 1 && equal(ds[dtop].x,p[i].x))
{
if(p[i].y < ds[dtop].y)--dtop;
else continue;
}
if(dtop <= 1)ds[++dtop] = p[i];
else
{
while(dtop >= 2 && slope(p[i],ds[dtop]) <= slope(ds[dtop],ds[dtop - 1]))--dtop;
ds[++dtop] = p[i];
}
}
double ans = 0;
for(int i = 1;i < utop;++i)ans += dis(us[i],us[i + 1]);
for(int i = 1;i < dtop;++i)ans += dis(ds[i],ds[i + 1]);
ans += dis(us[1],ds[1]);ans += dis(us[utop],ds[dtop]);
ans = ans + 2 * acos(-1) * r;
printf("%.2lf\n",ans);
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡