【洛谷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;

}

posted @ 2018-03-29 00:01  Greenty  阅读(155)  评论(0编辑  收藏  举报