小度熊有一个桌面,小度熊剪了很多矩形放在桌面上,小度熊想知道能把这些矩形包围起来的面积最小的矩形的面积是多少。
Time Limit: 20 Sec Memory Limit: 256 MB
http://acdream.info/problem?pid=1754
Input
第一行一个正整数 T,代表测试数据组数(1≤T≤20),接下来 T 组测试数据。
每组测试数据占若干行,第一行一个正整数 N(1≤N<≤1000),代表矩形的数量。接下来 N 行,每行 8 个整数x1,y1,x2,y2,x3,y3,x4,y4,代表矩形的四个点坐标,坐标绝对值不会超过10000。
Output
对于每组测试数据,输出两行:
第一行输出"Case #i:",i 代表第 i 组测试数据。 第二行包含1 个数字,代表面积最小的矩形的面积,结果保留到整数位。
Sample Input
2 2 5 10 5 8 3 10 3 8 8 8 8 6 7 8 7 6 1 0 0 2 2 2 0 0 2
Case #1: 17 Case #2: 4
题意
题解:
套版,套版
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define test freopen("test.txt","r",stdin) #define maxn 2000001 #define mod 10007 #define eps 1e-9 int Num; char CH[20]; const int inf=0x3f3f3f3f; const ll infll = 0x3f3f3f3f3f3f3f3fLL; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void P(int x) { Num=0;if(!x){putchar('0');puts("");return;} while(x>0)CH[++Num]=x%10,x/=10; while(Num)putchar(CH[Num--]+48); puts(""); } //************************************************************************************** struct Point { double x,y; Point(){} Point(double x0,double y0):x(x0),y(y0){} }; const int INF = 999999999; Point p[maxn]; int con[maxn]; int cn; int n; struct Line { Point a,b; Line(){} Line(Point a0,Point b0):a(a0),b(b0){} }; double xm(Point o,Point a,Point b) { return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y); } double dm(Point o,Point a,Point b) { return (a.x-o.x)*(b.x-o.x)+(a.y-o.y)*(b.y-o.y); } int sgn(double a) { return a<-eps?-1:a>eps; } double dist(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int cmp(Point a,Point b) { double d=xm(p[0],a,b); if(d>0) return 1; if(d==0 && dist(p[0],a)<dist(p[0],b)) return 1; return 0; } void Graham() { int i,ind=0; for(i=1;i<n;i++) if(p[ind].y>p[i].y || (p[ind].y==p[i].y) && p[ind].x>p[i].x) ind=i; swap(p[ind],p[0]); sort(p+1,p+n,cmp); con[0]=0; con[1]=1; cn=1; for(i=2;i<n;i++) { while(cn>0 && sgn(xm(p[con[cn-1]],p[con[cn]],p[i]))<=0) cn--; con[++cn]=i; } int tmp=cn; for(i=n-2;i>=0;i--) { while(cn>tmp && sgn(xm(p[con[cn-1]],p[con[cn]],p[i]))<=0) cn--; con[++cn]=i; } } double Solve() { int t,r,l; double ans=INF; t=r=1; if(cn<3) return 0; for(int i=0;i<cn;i++) { while(sgn(xm(p[con[i]],p[con[i+1]],p[con[t+1]])-xm(p[con[i]],p[con[i+1]],p[con[t]]))>0) t=(t+1)%cn; while(sgn(dm(p[con[i]],p[con[i+1]],p[con[r+1]])-dm(p[con[i]],p[con[i+1]],p[con[r]]))>0) r=(r+1)%cn; if(!i) l=r; while(sgn(dm(p[con[i]],p[con[i+1]],p[con[l+1]])-dm(p[con[i]],p[con[i+1]],p[con[l]]))<=0) l=(l+1)%cn; double d=dist(p[con[i]],p[con[i+1]]); double tmp=xm(p[con[i]],p[con[i+1]],p[con[t]])*(dm(p[con[i]],p[con[i+1]],p[con[r]])-dm(p[con[i]],p[con[i+1]],p[con[l]]))/d/d; ans=min(ans,tmp); } return ans; } int main() { int i; int T, cas = 0; scanf("%d", &T); while(T--) { scanf("%d", &n); n *= 4; for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); Graham(); printf("Case #%d:\n%.0f\n",++cas, Solve()); } return 0; }