标签:
在平面上有 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)
输出格式:
输出至屏幕。格式为:
一个整数,即满足条件的最小的矩形面积之和。
4 2
1 1
2 2
3 6
0 7
4
-------------------------------------------------------------------------------
看上去好吓人----然而与计算几何基本无关
DFS每个点,枚举矩形来覆盖那个点,搜完点更新答案
别忘要一个矩形覆盖一点dfs后把矩形改回原来的状态
就是那些几何运算的函数写的有点多
并且naocan的犯了一个沙茶问题,竟然这样写判断:lx<=x<=rx
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int N=55,INF=1e9; struct point{ int x,y; point(int a=0,int b=0):x(a),y(b){} }p[N]; struct squ{ int lx,ly,rx,ry; squ():lx(0),rx(0),ly(0),ry(0){} }s[N]; int n,k,ans=INF; inline bool isCover(int x,int y,int i){ if(s[i].lx<=x&&x<=s[i].rx && s[i].ly<=y&&y<=s[i].ry) return true; return false; } bool checkSqu(int i,int j){ squ a=s[i],b=s[j]; //if(a.lx==INF || b.lx==INF) return false; if(isCover(a.lx,a.ly,j)) return false; if(isCover(a.lx,a.ry,j)) return false; if(isCover(a.rx,a.ly,j)) return false; if(isCover(a.rx,a.ry,j)) return false; swap(a,b);swap(i,j); if(isCover(a.lx,a.ly,j)) return false; if(isCover(a.lx,a.ry,j)) return false; if(isCover(a.rx,a.ly,j)) return false; if(isCover(a.rx,a.ry,j)) return false; return true; } bool check(){ for(int i=1;i<=k;i++) for(int j=1;j<=k;j++){ if(i==j) continue; if(s[i].lx==INF||s[j].lx==INF) continue; if(!checkSqu(i,j)) return false; } return true; } int getS(){ int sum=0; for(int i=1;i<=k;i++){ squ &now=s[i]; if(now.lx==INF) continue; sum+=(now.rx-now.lx)*(now.ry-now.ly); } return sum; } void cover(point p,int i){ squ &a=s[i]; if(a.lx>p.x) a.lx=p.x; if(a.ly>p.y) a.ly=p.y; if(a.rx<p.x) a.rx=p.x; if(a.ry<p.y) a.ry=p.y; //printf("cover%d %d %d %d %d\n",i,s[i].lx,s[i].ly,s[i].rx,s[i].ry); } void dfs(int now){ //cout<<now<<" now\n"; if(now==n+1){ //cout<<getS()<<" s\n"; ans=min(ans,getS()); return; } if(getS()>=ans) return; for(int i=1;i<=k;i++){ squ tmp=s[i];//printf("hi%d %d %d %d %d\n",i,s[i].lx,s[i].ly,s[i].rx,s[i].ry); cover(p[now],i); if(check()) dfs(now+1); s[i]=tmp; //printf("tmp%d %d %d %d %d\n",i,s[i].lx,s[i].ly,s[i].rx,s[i].ry); } //cout<<now<<" end\n"; } int main(){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d%d",&p[i].y,&p[i].x);//daozhe } for(int i=1;i<=k;i++){ s[i].lx=s[i].ly=INF; s[i].rx=s[i].ry=-INF; } dfs(1); cout<<ans; }
标签:
原文地址:http://www.cnblogs.com/candy99/p/5785840.html