Rabbit的蛋糕(牛客36-f,计算几何,凸边形面积)

链接:https://ac.nowcoder.com/acm/contest/328/F
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld

题目描述

Rabbit和xxx获得了一个很大的蛋糕,这个蛋糕实际上是由N个点组成的凸多边形(点从1到N编号,保证没有三点共线)。
接着两个人开始分蛋糕,他们准备沿着蛋糕上两点连成的直线把蛋糕切成两份,由于Rabbit是女生,xxx总会把大的那一份分给Rabbit。现在有Q种切的方案,xxx可以选择任意一种,问xxx最多能分得多少蛋糕? 

输入描述:

第一行两个整数N,Q。

接下来N行,每行两个数xi,yi表示第i个点的坐标(点按逆时针顺序给出)。

接下来Q行,每行两个整数S,T表示切的两个点。

输出描述:

输出xxx最多能分得多少面积的蛋糕。

示例1

输入

4 2
0.5 0.5
10.5 0.5
10.5 10.5
0.5 10.5
1 3
4 2

输出

50.00

备注:

3<=n<=105

1<=q<=105

−105<=xi,yi<=105

1<=S,T<=N,S!=T

本题采用special judge,假设你的答案为a,标程答案为b,如果满足|a−b|max(1,|b|)≤10−4|a−b|max(1,|b|)≤10−4,则认为是正确的

ac:

#include<bits/stdc++.h>
#define ll long long
#define MAXN 100005
using namespace std;
double x[MAXN]={0},y[MAXN]={0};
int n,q;
int cc[MAXN]={0},dd[MAXN]={0};
double sum[MAXN]={0};
 
double sumc(int a,int b)
{
    return sqrt((x[b]-x[a])*(x[b]-x[a])+(y[b]-y[a])*(y[b]-y[a]));
}
 
double sums(int x,int y,int z)
{
    double a,b,c,p;
    a=sumc(x,y);
    b=sumc(y,z);
    c=sumc(x,z);
    p=(a+b+c)/2;
    return sqrt(p*(p-a)*(p-b)*(p-c));
}
 
double sums()
{
    double a,b,c,p;
    for(int i=1;i<=n-2;i++)
    {
        a=sumc(1,i+1);
        b=sumc(i+1,i+2);
        c=sumc(1,i+2);
        p=(a+b+c)/2;
        sum[i]=sum[i-1]+sqrt(p*(p-a)*(p-b)*(p-c));
    }
    return sum[n-2];
}
 
int main()
{
    double maxsum,asum,bsum,csum,maxminsum=0;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&x[i],&y[i]);
    for(int i=0;i<q;i++)
        scanf("%d%d",&cc[i],&dd[i]);
    maxsum=sums();
    for(int i=0;i<q;i++)
    {
        if(cc[i]>dd[i])
            swap(cc[i],dd[i]);
        if(cc[i]+1==dd[i]) continue;
        if(cc[i]==1)
        {
            asum=sum[dd[i]-2];
            bsum=sum[n-2]-asum;
            //cout<<asum<<" "<<bsum<<endl;
            csum=min(asum,bsum);
        }
        else{
            asum=sum[dd[i]-2]-sum[cc[i]-2]-sums(1,cc[i],dd[i]);
            bsum=sum[n-2]-asum;
            //cout<<asum<<" "<<bsum<<endl;
            csum=min(asum,bsum);
        }
        if(csum>maxminsum)
            maxminsum=csum;
    }
    cout<<maxminsum<<endl;
    //cout<<sum[n-2]<<endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/wangtao971115/p/10358213.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值