bzoj 4581: [Usaco2016 Open]Field Reduction (dfs)

4581: [Usaco2016 Open]Field Reduction

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 80   Solved: 13
[ Submit][ Status][ Discuss]

Description

Farmer John's N cows (5≤N≤50,000) are all located at distinct positions in his two-dimensional fie
ld. FJ wants to enclose all of the cows with a rectangular fence whose sides are parallel to the x a
nd y axes, and he wants this fence to be as small as possible so that it contains every cow (cows on
 the boundary are allowed).FJ is unfortunately on a tight budget due to low milk production last qua
rter. He would therefore like to build an even smaller fenced enclosure if possible, and he is willi
ng to sell up to three cows from his herd to make this possible.Please help FJ compute the smallest 
possible area he can enclose with his fence after removing up to three cows from his herd (and there
after building the tightest enclosing fence for the remaining cows).For this problem, please treat c
ows as points and the fence as a collection of four line segments (i.e., don't think of the cows as 
"unit squares"). Note that the answer can be zero, for example if all remaining cows end up standing
 in a common vertical or horizontal line.
给定平面上N个点。现你可以删去至多3个点,接着你需要用一个矩形包含所有的点,点可以在矩形的边上,矩形的
边须与坐标轴平行。最小化矩形的面积并输出这个值。
5 ≤ N ≤ 50000, 1 ≤ X_i, Y_i ≤ 40000

Input

The first line of input contains N.
The next N lines each contain two integers specifying the locati
on of a cow. Cow locations are positive integers in the range 1…40,000.

Output

 Write a single integer specifying the minimum area FJ can enclose with his fence after removing up t

o three carefully-chosen cows from his herd.

Sample Input

6
1 1
7 8
10 9
8 12
4 100
50 7

Sample Output

12

HINT

Source

[ Submit][ Status][ Discuss]


题解:dfs

删中间的点其实是没有用的,只有删四周边界的点才可以,所以我可以dfs这三个点分别选自那个边界,然后求所有状态中的最小值即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 50003
#define inf 1000000000
#define LL long long 
using namespace std;
int n,m;
LL ans;
struct data{
	LL x,y;
	int num;
}a[N];
int l[N],r[N],h[N],d[N],vis[N];
int cmp(data a,data b){return a.x<b.x; }
int cmp1(data a,data b){return a.x>b.x;}
int cmp2(data a,data b){return a.y<b.y;}
int cmp3(data a,data b){return a.y>b.y;}
LL calc()
{
	LL mnx=(LL)inf; LL mny=(LL)inf; LL mxx=(LL)-inf; LL mxy=(LL)-inf;
	for (int i=1;i<=n;i++){
		if (vis[a[i].num]) continue;
		mnx=min(mnx,a[i].x); mxx=max(mxx,a[i].x);
		mxy=max(mxy,a[i].y); mny=min(mny,a[i].y);
	}
	return (mxx-mnx)*(mxy-mny);
}
void dfs(int x,int ll,int rr,int hh,int dd)
{
	if (x==4) {
		ans=min(ans,calc());
		return;
	}
	//for (int i=1;i<=4;i++){
		//if (i==1) {
			int t=ll;
			while (vis[l[t]]) t++;
			vis[l[t]]=1;
			dfs(x+1,t+1,rr,hh,dd);
			vis[l[t]]=0;
		//}
		//if (i==2) {
			t=rr;
			while (vis[r[t]]) t++;
			vis[r[t]]=1;
			dfs(x+1,ll,t+1,hh,dd);
			vis[r[t]]=0;
		//}
		//if (i==3){
			t=hh;
			while (vis[h[t]]) t++;
			vis[h[t]]=1;
			dfs(x+1,ll,rr,t+1,dd);
			vis[h[t]]=0;
		//}
		//if (i==4){
			t=dd;
			while(vis[d[t]]) t++;
			vis[d[t]]=1;
			dfs(x+1,ll,rr,hh,t+1);
			vis[d[t]]=0;
		//}
//	}
}
int main()
{
	freopen("reduce.in","r",stdin);
	freopen("reduce.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%I64d%I64d",&a[i].x,&a[i].y),a[i].num=i;
	sort(a+1,a+n+1,cmp);
	for (int i=1;i<=15;i++) l[i]=a[i].num;
	sort(a+1,a+n+1,cmp1);
	for (int i=1;i<=15;i++) r[i]=a[i].num;
	sort(a+1,a+n+1,cmp2);
	for (int i=1;i<=15;i++) h[i]=a[i].num;
	sort(a+1,a+n+1,cmp3);
	for (int i=1;i<=15;i++) d[i]=a[i].num;
	ans=calc(); //cout<<ans<<endl;
	dfs(1,1,1,1,1);
	printf("%I64d\n",ans);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值