牛客练习赛36-F:Rabbit的蛋糕(计算几何)

链接: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行,每行两个数 x i , y i x_i,y_i xiyi表示第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 < = 1 0 5 3<=n<=10^5 3<=n<=105
1 < = q < = 1 0 5 1<=q<=10^5 1<=q<=105
− 1 0 5 < = x i , y i < = 1 0 5 −10^5<=x_i,y_i<=10^5 105<=xi,yi<=105
1 < = S , T < = N , S ! = T 1<=S,T<=N,S!=T 1<=S,T<=NS!=T
本题采用special judge,假设你的答案为a,标程答案为b,如果满足 ∣ a − b ∣ m a x ( 1 , ∣ b ∣ ) ≤ 1 0 − 4 \frac{|a−b|}{max(1,|b|)}≤10^{−4} max(1,b)ab104,则认为是正确的。
思路:计算S,T两点连线分割多边形所得到的某一半的面积,可以利用叉积来求,从S点开始遍历到T点,即: A r e a = ∑ i = S + 1 T ( x i − x s ) ( y i − 1 − y s ) − ( x i − 1 − x s ) ( y i − y s ) Area=\sum_{i=S+1}^{T} (x_i-x_s)(y_{i-1}-y_s)-(x_{i-1}-x_s)(y_i-y_s) Area=i=S+1T(xixs)(yi1ys)(xi1xs)(yiys)
化简可得: A r e a = ∑ i = S + 1 T x i y i − 1 − x i − 1 y i + x s ( y i − y i − 1 ) + y s ( x i − 1 − x i ) Area=\sum_{i=S+1}^{T} x_iy_{i-1}-x_{i-1}y_i+x_s(y_i-y_{i-1})+y_s(x_{i-1}-x_i) Area=i=S+1Txiyi1xi1yi+xs(yiyi1)+ys(xi1xi)
然后就可以用前缀和记录了,遍历的时候再求答案即可。

#include
using namespace std;
const int MAX=1e5+10;
const int MOD=1e9+7;
typedef long long ll;
struct Point{double x,y;}p[MAX];
struct lenka{int s,t;}a[MAX];
Point operator-(Point A,Point B){return (Point){A.x-B.x,A.y-B.y};}
double operator^(Point A,Point B){return A.x*B.y-A.y*B.x;}
double Polyarea(Point *p,int n)
{
	double area=0;
	for(int i=1;i>n>>m;
    for(int i=0;i

你可能感兴趣的:(计算几何)