CF #330 D2 E
相当于给你一些点,要你最多删除不超过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;
}
}

浙公网安备 33010602011771号