题目:pku1899 题意:已知一长方形麦地的长、宽,在它里面有一些圆形的UFO,用平行于x,y轴的长方形把UFO围起来,并使其面积最小, 从而使可以收割的面积最大。如果两个长方形相交,需将两者合并。 方法:计算几何(矩形相交)+DFS 代码:该代码参考何长兵的博客 //1 <= x, y <= 1000 0 <= N <= 100. #include <iostream> using namespace std; struct point { int x,y; }; struct circle { int x,y,r; }; struct rectangle { point ld,rp; }; circle c[105]; rectangle r[105]; int n,used[105]; // 判断两个矩形是否相交 bool rectangle_cross(rectangle a,rectangle b) { if(a.rp.x>=b.ld.x&&a.rp.y>=b.ld.y&&a.ld.x<=b.rp.x&&a.ld.y<=b.rp.y) return true; return false; } // 将相交的矩形合并 void dfs(int i,int j) { if(r[i].ld.x>r[j].ld.x)r[i].ld.x=r[j].ld.x; if(r[i].ld.y>r[j].ld.y)r[i].ld.y=r[j].ld.y; if(r[i].rp.x<r[j].rp.x)r[i].rp.x=r[j].rp.x; if(r[i].rp.y<r[j].rp.y)r[i].rp.y=r[j].rp.y; used[j]=1; for(int k=0;k<n;k++) { if(used[k]||k==i||k==j)continue; if(rectangle_cross(r[i],r[k]))dfs(i,k); } } int main() { int x,y; int i,j,k; while(cin>>x>>y) { cin>>n; memset(used,0,sizeof(used)); for(i=0;i<n;i++) { cin>>c[i].x>>c[i].y>>c[i].r; r[i].ld.x=c[i].x-c[i].r;r[i].ld.y=c[i].y-c[i].r; r[i].rp.x=c[i].x+c[i].r;r[i].rp.y=c[i].y+c[i].r; } for(i=0;i<n-1;i++) { if(used[i])continue; for(j=i+1;j<n;j++) { if(used[j])continue; if(rectangle_cross(r[i],r[j]))dfs(i,j); } } long inside=0,ans; for(i=0;i<n;i++) { if(used[i])continue; inside+=(r[i].rp.x-r[i].ld.x)*(r[i].rp.y-r[i].ld.y); // 内部矩形的面积之和 } ans=x*y-inside; // 总面积减去里面矩形的面积即为答案 cout<<ans<<endl; } return 0; }