标签:
题目链接:sicily 1071
解题思路:
题目要求我们把大的矩形分得尽量小,那么当我们把一个矩形分成两部分之后,自然会想到分出来的这两个矩形还能不能继续划分,这样就很自然地想到了递归。确定了大概思路之后,我们就得来解决细节——如何判定矩形能否被划分?
具体来说是这样做的,以寻找x轴方向划分线为例,首先,把矩形按照x轴坐标进行排序,之后遍历每个矩形,如果矩形的右边界的边为划分线,那么左边所有矩形(包括该矩形)的面积之和必然等于划分之后左边的矩形之和,由此判断。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,w,h,ans;
struct node{
int x1,y1,x2,y2;
int area;
node(int x1=0, int y1=0, int x2=0, int y2=0):
x1(x1),y1(y1),x2(x2),y2(y2){}
}a[105];
bool cmpx(node a, node b){
return a.x1<b.x1||(a.x1==b.x1&&a.x2<b.x2);
}
bool cmpy(node a, node b){
return a.y1<b.y1||(a.y1==b.y1&&a.y2<b.y2);
}
void cal (int x1,int y1,int x2,int y2,int l,int r);
bool cutx(int x1,int y1,int x2,int y2,int l,int r);
bool cuty(int x1,int y1,int x2,int y2,int l,int r);
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&w,&h);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d %d %d %d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
a[i].area=(a[i].x2-a[i].x1)*(a[i].y2-a[i].y1);
}
ans=0;
cal(0,0,w,h,0,n-1);
printf("%d\n",ans);
}
return 0;
}
void cal(int x1,int y1,int x2,int y2,int l,int r)
{
int area=(y2-y1)*(x2-x1);
if(area<=ans) //剪枝
return;
if(cutx(x1,y1,x2,y2,l,r))
return;
if(cuty(x1,y1,x2,y2,l,r))
return;
ans=max(ans,area);
}
bool cutx(int x1,int y1,int x2,int y2,int l,int r)
{
sort(a+l,a+r+1,cmpx);
int area=0,x=x1;
for(int i=l;i<r;i++)
{
area+=a[i].area;
x=max(x,a[i].x2);
if(area==(x-x1)*(y2-y1))
{
cal(x1,y1,x,y2,l,i);
cal(x,y1,x2,y2,i+1,r);
return 1;
}
}
return 0;
}
bool cuty(int x1,int y1,int x2,int y2,int l,int r)
{
sort(a+l,a+r+1,cmpy);
int area=0,y=y1;
for(int i=l;i<r;i++)
{
area+=a[i].area;
y=max(y,a[i].y2);
if(area==(y-y1)*(x2-x1))
{
cal(x1,y1,x2,y,l,i);
cal(x1,y,x2,y2,i+1,r);
return 1;
}
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/fuyukai/article/details/46504329