链接:https://ac.nowcoder.com/acm/contest/328/F
来源:牛客网
题目描述
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,则认为是正确的
多边形面积显然很好求,就是邻边叉积之和/2。
代码;
#include<bits/stdc++.h>
#define db double
using namespace std;
const int maxn=1e5+10;
db x[maxn],y[maxn],sum1[maxn],sum2[maxn],ans;
int main()
{
int n,q,s,t;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&x[i],&y[i]);
y[n+1]=y[1],x[n+1]=x[1];
for(int i=1;i<=n;i++)
{
sum1[i]=sum1[i-1]+x[i]*y[i+1];
sum2[i]=sum2[i-1]+y[i]*x[i+1];
}
db S=(sum1[n]-sum2[n])/2;
while(q--)
{
scanf("%d%d",&s,&t);
if(s>t)swap(s,t);
db t1=sum1[t-1]-sum1[s-1]+x[t]*y[s];
db t2=sum2[t-1]-sum2[s-1]+y[t]*x[s];
db tmp=(t1-t2)/2;
ans=max(ans,min(tmp,S-tmp));
}
printf("%.2lf\n",ans);
}