旋转卡壳求最小矩形覆盖的模板题。
因为最小矩形必定与凸包的一条边平行,则枚举凸包的边,通过旋转卡壳的思想去找到其他3个点,构成矩形,求出最小面积即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<set> 7 #include<map> 8 #include<stack> 9 #include<time.h> 10 #include<cstdlib> 11 #include<cmath> 12 #include<list> 13 using namespace std; 14 #define MAXN 100100 15 #define eps 1e-9 16 #define For(i,a,b) for(int i=a;i<=b;i++) 17 #define Fore(i,a,b) for(int i=a;i>=b;i--) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 #define mkp make_pair 21 #define pb push_back 22 #define cr clear() 23 #define sz size() 24 #define met(a,b) memset(a,b,sizeof(a)) 25 #define iossy ios::sync_with_stdio(false) 26 #define fre freopen 27 #define pi acos(-1.0) 28 #define inf 1e6+7 29 #define Vector Point 30 const int Mod=1e9+7; 31 typedef unsigned long long ull; 32 typedef long long ll; 33 int dcmp(double x){ 34 if(fabs(x)<=eps) return 0; 35 return x<0?-1:1; 36 } 37 struct Point{ 38 double x,y; 39 Point(double x=0,double y=0):x(x),y(y) {} 40 bool operator < (const Point &a)const{ 41 if(x==a.x) return y<a.y; 42 return x<a.x; 43 } 44 Point operator - (const Point &a)const{ 45 return Point(x-a.x,y-a.y); 46 } 47 Point operator + (const Point &a)const{ 48 return Point(x+a.x,y+a.y); 49 } 50 Point operator * (const double &a)const{ 51 return Point(x*a,y*a); 52 } 53 Point operator / (const double &a)const{ 54 return Point(x/a,y/a); 55 } 56 void read(){ 57 scanf("%lf%lf",&x,&y); 58 } 59 void out(){ 60 cout<<"debug: "<<x<<" "<<y<<endl; 61 } 62 bool operator == (const Point &a)const{ 63 return dcmp(x-a.x)==0 && dcmp(y-a.y)==0; 64 } 65 }; 66 double Dot(Vector a,Vector b) { 67 return a.x*b.x+a.y*b.y; 68 } 69 double dis(Vector a) { 70 return sqrt(Dot(a,a)); 71 } 72 double Cross(Point a,Point b){ 73 return a.x*b.y-a.y*b.x; 74 } 75 int ConvexHull(Point *p,int n,Point *ch){ 76 int m=0; 77 For(i,0,n-1) { 78 while(m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; 79 ch[m++]=p[i]; 80 } 81 int k=m; 82 Fore(i,n-2,0){ 83 while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--; 84 ch[m++]=p[i]; 85 } 86 if(n>1) m--; 87 return m; 88 } 89 double ANS(Point *p,int n){ 90 int L,R=1,U=1; 91 double ans=1e9+9; 92 p[n]=p[0]; 93 For(i,0,n-1) { 94 while(Cross(p[i+1]-p[i],p[U+1]-p[i])>=Cross(p[i+1]-p[i],p[U]-p[i])) U=(U+1)%n; 95 while(Dot(p[i+1]-p[i],p[R+1]-p[i])>Dot(p[i+1]-p[i],p[R]-p[i])) R=(R+1)%n; 96 if(!i) L=R; 97 while(Dot(p[i+1]-p[i],p[L+1]-p[i])<=Dot(p[i+1]-p[i],p[L]-p[i])) L=(L+1)%n; 98 double tmp=fabs(Cross(p[U]-p[i],p[i+1]-p[i]))/dis(p[i+1]-p[i]); 99 double cnt1=fabs(Dot(p[L]-p[i],p[i+1]-p[i]))/dis(p[i+1]-p[i]),cnt2=fabs(Dot(p[R]-p[i],p[i+1]-p[i]))/dis(p[i+1]-p[i]); 100 ans=min(ans,(cnt2+cnt1)*tmp); 101 } 102 return ans; 103 } 104 int n,m; 105 Point p[200005]; 106 Point ch[200005]; 107 void solve(){ 108 scanf("%d",&n); 109 int rt=0; 110 For(i,0,n-1) { 111 p[rt++].read(); 112 p[rt++].read(); 113 p[rt++].read(); 114 p[rt++].read(); 115 } 116 sort(p,p+rt); 117 m=ConvexHull(p,rt,ch); 118 printf("%.0lf\n",ANS(ch,m)); 119 } 120 int main(){ 121 // fre("in.txt","r",stdin); 122 int t=0; 123 cin>>t; 124 For(i,1,t) printf("Case #%d:\n",i),solve(); 125 return 0; 126 }