Wrapping
【题目链接】Wrapping
【题目类型】凸包
&题解:
蓝书 凸包入门模板题
【时间复杂度】(O(nlogn))
&代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
struct Point {
double x,y;
Point(double x=0,double y=0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator + (const Vector& A,const Vector& B) {return Vector(A.x+B.x , A.y+B.y);}
Vector operator - (const Vector& A,const Vector& B) {return Vector(A.x-B.x , A.y-B.y);}
bool operator < (const Point& a,const Point& b) {return a.x<b.x||(a.x==b.x&&a.y<b.y);}
bool operator == (const Point& a,const Point& b) {return a.x==b.x&&a.y==b.y;}
double Cross(const Vector&A,const Vector& B) {return A.x*B.y-A.y*B.x;}
Vector Rotate(const Vector& A,double a) {return Vector(A.x*cos(a)-A.y*sin(a) , A.x*sin(a)+A.y*cos(a));}
double PolygonArea(vector<Point> p) {
double ans=0;
for(int i=1; i<p.size()-1; i++) {
ans+=Cross(p[i]-p[0],p[i+1]-p[0]);
}
//这块返回的面积要除2啊 不要忘了
return ans/2;
}
vector<Point> ConvexHull(vector<Point> p) {
sort(p.begin(),p.end());
p.erase(unique(p.begin(), p.end()),p.end());
int n=p.size();
vector<Point> ch(n+1);
int m=0;
for(int i=0; i<n; i++) {
while(m>1&&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&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
ch[m++]=p[i];
}
if (n>1) m--;
ch.resize(m);
return ch;
}
double torad(double x) {return x/180*acos(-1);}
int n;
double w,h,j;
Point o;
int main() {
//("e:1.in","r",stdin);
int T; scanf("%d",&T);
while(T--) {
vector<Point> p;
scanf("%d",&n);
int m=0;
double area1=0;
for(int i=0; i<n; i++) {
scanf("%lf%lf%lf%lf%lf",&o.x,&o.y,&w,&h,&j);
area1+=w*h;
double ang=-torad(j);
p.push_back(o+Rotate(Vector(-w/2,-h/2),ang));
p.push_back(o+Rotate(Vector(-w/2,h/2),ang));
p.push_back(o+Rotate(Vector(w/2,-h/2),ang));
p.push_back(o+Rotate(Vector(w/2,h/2),ang));
}
vector<Point> te=ConvexHull(p);
double area2=PolygonArea(te);
printf("%.1f %%
", area1*100/area2);
// printf("te.size() = %d area1 = %f area2 = %f
", te.size(),area1,area2);
}
return 0;
}