题目链接

这题如果每个信用卡都不一样不知道怎么做啊……萌新求大佬私信指点迷津qaq

题目大意:给定一个矩形,将其四角替换为\(\frac{1}{4}\)圆弧(也就是信用卡的样子),将这个矩形进行旋转和平移之后得到多个矩形,求凸包长

计算几何


分析:旋转什么的基本操作,我们看比较恶心的圆弧怎么算

样例一可以知道如果\(r=0\)我们直接对矩形顶点求凸包就好,如果\(r\neq0\)我们可以通过平移,将其周长转化为若干个圆心点的凸包周长加一个圆的周长

这个操作可以理解为将凸包整体向内收缩了\(r\),所以不影响正确性,然后我们直接求一个朴素凸包周长最后加上一个半径为\(r\)的圆周长即可

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 5e4 + 100;
const double pi = acos(-1),eps = 1e-4;
struct Point{
	double x,y;
}p[maxn],stk[maxn],w[4],org;
typedef Point Vector;
inline Vector operator + (Vector a,Vector b){return Vector{a.x + b.x,a.y + b.y};}
inline Vector operator - (Vector a,Vector b){return Vector{a.x - b.x,a.y - b.y};}
inline Vector rotate(Vector now,double theta){return Vector{now.x * cos(theta) - now.y * sin(theta),now.x * sin(theta) + now.y * cos(theta)};}
inline double cross(Vector a,Vector b){return a.x * b.y - a.y * b.x;}
inline double sq(double x){return x * x;}
inline double dis(Point a,Point b){return sqrt(sq(a.x - b.x) + sq(a.y - b.y));}
inline int dcmp(double x){return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1);}
inline bool operator < (Point a,Point b){
	double tmp = cross(a - org,b - org);
	if(dcmp(tmp) > 0)return true;
	else if(dcmp(tmp) == 0 && dis(org,a) < dis(org,b))return true;
	else return false;
} 
istream& operator >> (istream &in,Point &x){
	in >> x.x >> x.y;
	return in;
}
ostream& operator << (ostream &out,Point &x){
	out << x.x << " " << x.y;
	return out;
}
int n,tot,top;
double a,b,r,ans;
int main(){
	ios::sync_with_stdio(false);
	cout << setiosflags(ios::fixed) << setprecision(2);
	cin >> n;
	cin >> a >> b >> r;
	w[0] = Vector{-0.5 * b + r,0.5 * a - r};
	w[1] = Vector{0.5 * b - r,0.5 * a - r};
	w[2] = Vector{0.5 * b - r,-0.5 * a + r};
	w[3] = Vector{-0.5 * b + r,-0.5 * a + r};
	for(int i = 1;i <= n;i++){
		Point from;double theta;
		cin >> from >> theta;
		for(int i = 0;i < 4;i++)
			p[++tot] = from + rotate(w[i],theta);
	}
	org = p[1];
	for(int i = 1;i <= tot;i++)
		if(p[i].y < org.y || (p[i].y == org.y && p[i].x < org.x))org = p[i];
	sort(p + 1,p + 1 + tot);
	stk[++top] = p[1];
	for(int i = 2;i <= tot;i++){
		while(top > 1 && dcmp(cross(stk[top - 1] - stk[top],p[i] - stk[top])) >= 0)top--;
		stk[++top] = p[i];
	}
	stk[top + 1] = p[1];
	for(int i = 1;i <= top;i++)ans += dis(stk[i],stk[i + 1]);
	ans += pi * 2 * r;
	cout << ans << '\n';
	return 0;
}

相关文章:

  • 2021-12-10
  • 2021-04-27
  • 2021-12-06
  • 2021-11-06
  • 2021-06-21
  • 2021-12-13
  • 2018-05-18
  • 2018-08-17
猜你喜欢
  • 2021-10-19
  • 2021-01-04
  • 2020-03-17
  • 2021-10-19
  • 2021-10-19
  • 2021-11-04
  • 2021-06-27
  • 2019-03-31
相关资源
相似解决方案