【洛谷P1378】油滴扩展
题目
在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pirr,其中r为圆的半径。
分析
用stl自带的next_permutation 枚举油滴扩展的顺序(最多720种)
每确定一种顺序,求一次答案
贪心地将当前点扩展到最大,如果当前点已经被前面的油滴覆盖到,那么这个点不放油滴 , 画图可以感性认识,这种情况最大,不知道怎么证明...
最后输出答案,四舍五入就是将当前的小数答案+0.5 再向下取整
代码
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a); i<=(b) ; i++)
#define _For(i,a,b) for(int i=(a); i>=(b) ; i--)
#define Memset(a,b); memset((a),(b),sizeof((a)));
#define Cout(a,b); printf("%d",(a));printf(b);
#define Coutc(a,b); printf("%c",(a));printf(b);
#define Couts(a,b); printf("%s",(a));printf(b);
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;typedef unsigned long long ULL;typedef long double LDB;
inline LL CinLL(){LL x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
inline int Cin(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return f*x;}
struct cre{
double x,y,r,are;
bool use;
}a[10];
const double p = acos(-1);
const double eps = 1e-8;
double xx1,yy1,xx2,yy2;
int n;
int sx[] = {0,1,2,3,4,5,6};
inline double dis(double xa,double ya,double xb,double yb){
return sqrt((xb - xa) * (xb - xa) + (yb - ya ) * (yb - ya));
}
double solve()
{
For(i,1,n)
{
int now = sx[i];
double rr = 99999999;
int flag = 0;
For(j,1,i-1)
if(dis(a[now].x,a[now].y,a[sx[j]].x,a[sx[j]].y) <= a[sx[j]].r){
a[now].use = false;flag = 1;break;
}
if(flag)continue;
For(c,1,i-1){
int j= sx[c];if(a[j].use == false) continue;
double kk = dis(a[now].x,a[now].y,a[j].x,a[j].y) - a[j].r;
rr = rr < kk ? rr : kk;
}
rr = rr < (a[now].x - xx1) ? rr : (a[now].x - xx1);
rr = rr < (xx2 - a[now].x) ? rr : (xx2 - a[now].x);
rr = rr < (a[now].y - yy1) ? rr : (a[now].y - yy1);
rr = rr < (yy2 - a[now].y) ? rr : (yy2 - a[now].y);
a[now].r = rr;
a[now].are = p * a[now].r * a[now].r;
a[now].use = true;
}
double sum = 0;
For(i,1,n) sum += a[i].are;
return sum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
cin>>xx1>>yy1>>xx2>>yy2;
if(xx1 > xx2){
swap(xx1,xx2);swap(yy1,yy2);
}
if(yy1 > yy2) swap(yy1,yy2);
For(i,1,n) cin>>a[i].x>>a[i].y;
double ans = 0;
double tim = 1;
For(i,2,n) tim*=i;
For(i,1,tim)
{
For(j,1,n) {
a[j].are = a[j].r = 0;
a[j].use = false;
}
double k = solve();
ans = ans > k ? ans : k;
next_permutation(sx+1,sx+n+1);
}
double res = (xx2 - xx1) * (yy2 - yy1) - ans;
int ress = (res + 0.5+eps);
cout<<ress;
}