[LG1378] 油滴扩展

暴力枚举油滴的编号的排列(next_permutation),然后按序一个一个扩展。面积的求最小值即可。也可以深搜。

复杂度 \(O(n!\times n^2)\).

#include<cstdio>
#include<algorithm>
#include<cmath>
#define sq(a) ((a)*(a))
#define PI 3.1415926535897932626
using namespace std;
int n,l,r,u,d;//rtg
int x[10],y[10];//point
int p[10];//permutation
double ra[10];// 半径
double dis[10][10];//distance
double ans;

int main(){
    scanf("%d",&n);
	scanf("%d%d%d%d",&l,&u,&r,&d);
	if(l>r)l^=r^=l^=r;//l<=r
	if(u>d)u^=d^=u^=d;//u<=d
	for(int i=1;i<=n;i++){
        scanf("%d%d",&x[i],&y[i]);
		for(int j=1;j<i;j++){
            dis[i][j]=dis[j][i]=sqrt(sq(x[i]-x[j])+sq(y[i]-y[j]));
		}
	}

	for(int i=1;i<=n;i++)p[i]=i;
	do{for(int i=1;i<=n;i++)ra[i]=1e9;//init
		for(int i=1;i<=n;i++){//p[i]
			ra[i]=min(ra[i],(double)x[p[i]]-l);
			ra[i]=min(ra[i],(double)r-x[p[i]]);
			ra[i]=min(ra[i],(double)y[p[i]]-u);
			ra[i]=min(ra[i],(double)d-y[p[i]]);
			for(int j=1;j<i;j++){
                ra[i]=min(ra[i],(double)dis[p[i]][p[j]]-ra[j]);
			}
			ra[i]=max(ra[i],(double)0);// 如果为负数
		}
		double s=0;
		for(int i=1;i<=n;i++)s+=sq(ra[i])*PI;
		ans=max(ans,s);
	}while(next_permutation(p+1,p+n+1));
	ans=(r-l)*(d-u)-ans;
	printf("%d",(int)ans+1-(ans-(int)ans<0.5));
	return 0;
}
posted @ 2019-06-15 08:14  Sshwy  阅读(84)  评论(0编辑  收藏  举报