列表

详情


NC21731. Rabbit的蛋糕

描述

Rabbit和xxx获得了一个很大的蛋糕,这个蛋糕实际上是由N个点组成的凸多边形(点从1N编号,保证没有三点共线)。
接着两个人开始分蛋糕,他们准备沿着蛋糕上两点连成的直线把蛋糕切成两份,由于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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 117ms, 内存消耗: 2280K, 提交时间: 2019-01-04 20:26:03

#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);
}

C++11(clang++ 3.9) 解法, 执行用时: 83ms, 内存消耗: 2424K, 提交时间: 2019-01-04 22:15:27

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
using namespace std;
const int N=1e5+5;
int n,m; double sum[N],ans;
struct P{
	double x,y; P(double x=0,double y=0):x(x),y(y){}
	double det(P t){return x*t.y-y*t.x;}
}a[N];
int main(){
	scanf("%d%d",&n,&m);
	rep (i,1,n) scanf("%lf%lf",&a[i].x,&a[i].y); a[n+1]=a[1];
	rep (i,1,n) sum[i]=sum[i-1]+a[i].det(a[i+1]);
	while (m--){
		int x,y; scanf("%d%d",&x,&y);
		if (x>y) swap(x,y);
		double t=sum[y-1]-sum[x-1]-a[x].det(a[y]);
		ans=max(min(t,sum[n]-t),ans);
	}
	printf("%lf\n",ans/2);
	return 0;
}

上一题