1. 程式人生 > >最小面積2 [模擬][dfs]

最小面積2 [模擬][dfs]

傳送門

訓練思維與程式碼能力的好題

題目要求取出3個點 , 發現這3個點一定是在最外3層 , 這樣才是最優的

把最外的4層的點取出來(第4層用來統計答案) , dfs選3個點刪除就好

#include<bits/stdc++.h>
#define N 50050
#define inf 0x7fffffff
using namespace std;
struct Node{int x,y,id;}a[N],tmp[N],res[N];
int vis[N],n,tot,ans=inf;
bool cmp1(Node a,Node b){return a.x<b.x;}
bool cmp2(Node a,Node b){return a.y<b.y;}
int calc(){
	int ans = 0;
	int k=0; for(int i=1;i<=tot;i++)
		if(!vis[i]) res[++k]=tmp[i];
	sort(res+1,res+k+1,cmp1); ans = res[k].x - res[1].x;
	sort(res+1,res+k+1,cmp2); ans *= (res[k].y - res[1].y);
	return ans;
}
void dfs(int pos,int cnt){
	if(cnt==3){ans = min(ans,calc()); return;}
	if(pos>tot) return;
	vis[pos] = 1; dfs(pos+1,cnt+1);
	vis[pos] = 0; dfs(pos+1,cnt);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].x,&a[i].y);
		a[i].id = i;
	} sort(a+1,a+n+1,cmp1); 
	for(int i=1;i<=4;i++) if(!vis[a[i].id]) 
		tmp[++tot] = a[i] , vis[a[i].id] = 1;
	for(int i=n-3;i<=n;i++) if(!vis[a[i].id])
		tmp[++tot] = a[i] , vis[a[i].id] = 1;
	sort(a+1,a+n+1,cmp2);
	for(int i=1;i<=4;i++) if(!vis[a[i].id]) 
		tmp[++tot] = a[i] , vis[a[i].id] = 1;
	for(int i=n-3;i<=n;i++) if(!vis[a[i].id])
		tmp[++tot] = a[i] , vis[a[i].id] = 1;
	memset(vis,0,sizeof(vis)); dfs(1,0);
	printf("%d",ans); return 0;
}