相当于给你一些点,要你最多删除不超过k,使得能使用一个边长为整数的长方形,与XY轴平行,使长方形的面积最小。
上课时拿笔来画画,然后忽然思路就开了,要是比赛也这样就好了~~先按X,Y分别排序,由于K较小,而且,删除的时候肯定会删除最外围的点,所以,可以上下左右枚举删了哪些点,排序后的数组来模拟这个过程,最多4^K个选择,可以过。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define LL long long using namespace std; ///vector<int>f; const int MAX=100050; struct Point{ double x,y; int index; }ptx[MAX],pty[MAX]; bool cmpx(Point a,Point b){ if(a.x<b.x) return true; return false; } bool cmpy(Point a,Point b){ if(a.y<b.y) return true; return false; } bool vis[MAX]; int n,k; LL ans; void dfs(int wl,int wr,int hl,int hr,int counts){ if(!counts){ while(vis[ptx[wl+1].index]) wl++; while(vis[ptx[wr-1].index]) wr--; while(vis[pty[hl+1].index]) hl++; while(vis[pty[hr-1].index]) hr--; LL x=(ptx[wr-1].x-ptx[wl+1].x==0)?1:(LL)(ptx[wr-1].x-ptx[wl+1].x+0.5); LL y=(pty[hr-1].y-pty[hl+1].y==0)?1:(LL)(pty[hr-1].y-pty[hl+1].y+0.5); ans=min(ans,x*y); return ; } for(int i=wl+1;;i++){ if(vis[ptx[i].index]) continue; vis[ptx[i].index]=true; dfs(i,wr,hl,hr,counts-1); vis[ptx[i].index]=false; break; } for(int i=wr-1;;i--){ if(vis[ptx[i].index]) continue; vis[ptx[i].index]=true; dfs(wl,i,hl,hr,counts-1); vis[ptx[i].index]=false; break; } for(int i=hl+1;;i++){ if(vis[pty[i].index]) continue; vis[pty[i].index]=true; dfs(wl,wr,i,hr,counts-1); vis[pty[i].index]=false; break; } for(int i=hr-1;;i--){ if(vis[pty[i].index]) continue; vis[pty[i].index]=true; dfs(wl,wr,hl,i,counts-1); vis[pty[i].index]=false; break; } } int main(){ while(scanf("%d%d",&n,&k)!=EOF){ double x1,y1,x2,y2; for(int i=0;i<n;i++){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); ptx[i].x=(x1+x2)/2;ptx[i].y=(y1+y2)/2; ptx[i].index=i; pty[i]=ptx[i]; vis[i]=false; } sort(ptx,ptx+n,cmpx); sort(pty,pty+n,cmpy); ans=(1LL<<62); if(k==n-1){ cout<<1<<endl; continue; } dfs(-1,n,-1,n,k); cout<<ans<<endl; } }
时间: 2024-10-17 08:38:56