内存限制:256 MiB 时间限制:1000 ms
问题描述
小凸晚上喜欢到操场跑步,今天他跑完两圈之后,他玩起了这样一个游戏。
操场是个凸 n 边形,N 个顶点按照逆时针从 0∼n−1 编号。现在小凸随机站在操场中的某个位置,标记为 P 点。将 P 点与 n个顶点各连一条边,形成 N 个三角形。如果这时 P 点, 0 号点,1 号点形成的三角形的面积是 N个三角形中最小的一个,小凸则认为这是一次正确站位。
现在小凸想知道他一次站位正确的概率是多少。
输入格式
第一行包含 1 个整数 n ,表示操场的顶点数和游戏的次数。 接下来有 N 行,每行包含两个整数 Xi 、Yi表示顶点的坐标。
输入保证按逆时针顺序输入点,所有点保证构成一个 n 多边形。所有点保证不存在三点共线。
输出格式
输出一个数,正确站位的概率,保留 4 位小数。
样例输入 1
5
1 8
0 7
0 0
8 0
8 8
样例输出 1
0.6316
样例输入 2
4
0 0
7 0
5 5
-1 4
样例输出 2
0.2475
提示
3≤N≤10^5,−10^9≤X,Y≤10^9
题解
仅凭直觉和想象很难确定满足条件的点的位置(至少鄙人是这样……),这时候就需要用数学式帮助解题。根据题意,我们用叉乘求面积的方法(给点用叉乘,给边用海伦公式)写出一系列不等式(其实一组通式就够了),化简之后得到一组二元一次不等式。
在信息学中,我们通常用最短路(差分约束系统)来求解不等式组,然而本题只有两个变元且都带有系数,于是不能用图论算法解决。回忆在数学课上,我们通过线性规划的方法解二元一次不等式组,然而线性规划的过程不就是在求一个半平面交吗?于是本题就用半平面交解决。
注意一个小细节:鄙人使用直线左侧表示半平面,因此最后化简出的不等式都应大于零。
代码
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>