The Fortified Forest(暴力状态枚举+凸包)

太爽了!!!!1A

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>

using namespace std;


const int maxn=50;
const double eps=1e-8;

int sgn(double x)
{
    if(fabs(x)<eps)
        return 0;
    if(x<0)
        return -1;
    else
        return 1;
}
struct Point
{
    double x,y;
    double val,len;
    int index;
    Point(){}
    Point(double _x,double _y)
    {
        x=_x;
        y=_y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x-b.x,y-b.y);
    }
    double operator ^(const Point &b)const
    {
        return x*b.y-y*b.x;
    }
    double operator *(const Point &b)const
    {
        return x*b.x+y*b.y;
    }
};

Point p[maxn];
int num[maxn];
Point p1[maxn];
int Stack[maxn];
int top=0;
int p1_cont;


double dist(Point a,Point b)
{
    return sqrt((a-b)*(a-b));
}

bool cmp(Point a,Point b)
{
    int ans=sgn((a-p1[0])^(b-p1[0]));
    if(ans==1)
        return true;
    else if(ans==0)
        return dist(a,p1[0])<dist(b,p1[0]);
    else
        return false;
}
void graham()
{
    for(int i=0;i<p1_cont;i++)
    {
        if(p1[i].y<p1[0].y||(p1[i].y==p1[0].y&&p1[i].x<p1[0].x))
            swap(p1[0],p1[i]);
    }
    sort(p1+1,p1+p1_cont,cmp);
    if(p1_cont==1)
    {
        Stack[0]=0;
        top=0;
    }
    else if(p1_cont==2)
    {
        Stack[0]=0;
        Stack[1]=1;
        top=1;
    }
    else
    {
        Stack[0]=0;
        Stack[1]=1;
        top=1;
        for(int i=2;i<p1_cont;i++)
        {
             while(top>0&&((p1[Stack[top]]-p1[Stack[top-1]])^(p1[i]-p1[Stack[top-1]]))<=0)
                top--;
            top++;
            Stack[top]=i;
        }
    }
}

double getsa()
{
    double res=0;
    for(int i=1;i<=top;i++)
    {
        res+=dist(p1[Stack[i]],p1[Stack[i-1]]);
    }
    res+=dist(p1[Stack[top]],p1[0]);
    return res;
}

int main()
{

    int n;
    int Num=0;
    while(1)
    {
        cin>>n;
        if(n==0)
            break;
        Num++;
        for(int i=0;i<n;i++)
        {
            cin>>p[i].x>>p[i].y>>p[i].val>>p[i].len;
            p[i].index=i+1;
        }
        int max1=100000000;
        int ans[maxn];
        int ans_cont=0;
        double ans_s;
        for(int i=0;i<(1<<n);i++)
        {
            //printf("%d\n",i);
            int k=i;
            double val=0;
            double len=0;
            int cont=0;
            int cont1=0;
            p1_cont=0;
            while(cont!=n)
            {
                if((k&1)==1)
                {
                    val+=p[cont].val;
                    len+=p[cont].len;
                    num[cont1++]=p[cont].index;
                }
                else
                {
                    p1[p1_cont].x=p[cont].x;
                    p1[p1_cont].y=p[cont].y;
                    p1[p1_cont].val=p[cont].val;
                    p1[p1_cont].len=p[cont].len;
                    p1_cont++;
                }
                cont++;
                k=k>>1;
            }
            if(p1_cont==0)
                continue;
            graham();
            double s=getsa();
            if(len>=s)
            {
                if(val<max1||(val==max1&&cont1<ans_cont))
                {
                    max1=val;
                    ans_cont=cont1;
                    for(int i=0;i<cont1;i++)
                        ans[i]=num[i];
                    ans_s=len-s;
                }

            }
        }
        printf("Forest %d\n",Num);
        printf("Cut these trees: ");
        for(int i=0;i<ans_cont;i++)
            printf("%d ",ans[i]);
        printf("\n");
        printf("Extra wood: %.2lf\n",ans_s);
        printf("\n");
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值