题意:给定n个点,你需要找一个面积最小的矩形将其中的m个点严格的包裹在内。
题解:1、尽管求的是严格包裹在内的点,但也可以转化成求非严格,即点可以在边上的,两者对应关系就是x*y=(a+2)*(b+2)。
2、由于n、m都比较小,可以枚举矩形的xmin,xmax。
3、枚举确定xmin和xmax后,实际上矩形的一条边就确定了,要想面积最小,就是使得另一边尽可能的小,即从x坐标满足要求的点中选择m个y坐标最接近的,由于每个枚举都是共用一个数据,所以可以先将n个点按y坐标排序。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 struct point 6 { 7 int x,y; 8 }po[300]; 9 bool comp(point a,point b) 10 { 11 return a.y<b.y; 12 } 13 int x[300],n,m; 14 int getarea(int lx,int rx) 15 { 16 int d=20000; 17 int y[300],f=0,r=0; 18 for(int i=0;i<n;i++) 19 { 20 if(po[i].x>=lx&&po[i].x<=rx) 21 { 22 y[r++]=po[i].y; 23 if(r-f==m) 24 { 25 d=min(d,y[r-1]-y[f]); 26 f++; 27 } 28 } 29 } 30 return (d==20000)?(1<<30):(d+2)*(rx-lx+2); 31 } 32 int main() 33 { 34 int T; 35 for(scanf("%d",&T);T;T--) 36 { 37 int nu=0,ans=1<<30,sum; 38 scanf("%d%d",&n,&m); 39 for(int i=0;i<n;i++) 40 scanf("%d%d",&po[i].x,&po[i].y),x[i]=po[i].x; 41 if(m==1) 42 { 43 printf("4\n"); 44 continue; 45 } 46 sort(po,po+n,comp); 47 sort(x,x+n); 48 for(int i=1;i<n;i++) 49 if(x[i]!=x[nu]) 50 x[++nu]=x[i]; 51 nu++; 52 for(int i=0;i<nu;i++) 53 { 54 for(int j=i;j<nu;j++) 55 { 56 ans=min(ans,getarea(x[i],x[j])); 57 } 58 } 59 printf("%d\n",ans); 60 } 61 return 0; 62 }