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;
	}
	
}

  

原文地址:https://www.cnblogs.com/jie-dcai/p/4963492.html