题目描述
在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示。例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一。
这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴。当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4。问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢。约定:覆盖一个点的矩形面积为 0;覆盖平行于坐标轴直线上点的矩形面积也为0。各个矩形必须完全分开(边线与顶点也都不能重合)。
输入输出格式
输入格式:
n k xl y1 x2 y2 … …
xn yn (0<=xi,yi<=500)
输出格式:
输出至屏幕。格式为:
一个整数,即满足条件的最小的矩形面积之和。
输入输出样例
输入样例#1:
4 2
1 1
2 2
3 6
0 7
输出样例#1:
4
此题数据较水,考虑暴力搜索。
对于每一个点,有三种情况
1 被已有矩形包含
2 新开一个矩形
3 加入已有矩形中
剩下的,交给暴力吧。
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,ans=1e9+7,x[55],y[55];
struct sq
{
int x1,y1,x2,y2;
}a[15];
bool pd(int i,int k)
{
for(int j=1;j<=k;j++)
if(i!=j)
if(a[i].x1<=a[j].x2&&a[i].y1<=a[j].y2&&a[i].x2>=a[j].x1&&a[i].y2>=a[j].y1)
return 0;
return 1;
}
void dfs(int u,int k,int s)//第u个矩形,已经用了k个矩形
{
if(u>n)
{
if(s<ans)
ans=s;
return ;
}
for(int i=1;i<=k;i++)//判断是否被已有矩形包含
if(a[i].x1<=x[u]&&a[i].x2>=x[u]&&a[i].y1<=y[u]&&a[i].y2>=y[u])
{
dfs(u+1,k,s);
return ;
}
if(k<m)//新开一个
{
a[k+1].x1=a[k+1].x2=x[u],a[k+1].y1=a[k+1].y2=y[u];
dfs(u+1,k+1,s);
}
for(int i=1;i<=k;i++)//接在原来的一个上
{
sq tmp=a[i];
if(x[u]<a[i].x1)
a[i].x1=x[u];
else if(x[u]>a[i].x2)
a[i].x2=x[u];
if(y[u]<a[i].y1)
a[i].y1=y[u];
else if(y[u]>a[i].y2)
a[i].y2=y[u];
if(pd(i,k))
dfs(u+1,k,s-(tmp.x2-tmp.x1)*(tmp.y2-tmp.y1)+(a[i].x2-a[i].x1)*(a[i].y2-a[i].y1));
a[i]=tmp;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
dfs(1,0,0);
printf("%d\n",ans);
return 0;
}
本文探讨了一个几何问题:如何利用最少面积的矩形覆盖平面上的指定点集。通过递归搜索算法,解决了多个点使用特定数量矩形覆盖的问题,并确保了矩形之间互不相交。代码实现采用了C++语言。
621

被折叠的 条评论
为什么被折叠?



