題目
先推一波式子,設\(p(x,y)\),那麼我們嘗試寫出點\((x_i,y_i),(x_,y_)\)和\(p(x,y)\)形成的三角形面積,就是用叉積寫一波
\[2s=(x_i-x)(y_-y)-(x_-x)(y_i-y)
\]大力拆開式子,發現\(2s=(y_-y_)x+(x_-x_i)y+x_iy_-x_y_i\)
不難發現這是乙個\(ax+by+c\)的形式,肯定跟直線有點關係,我們設\(a_i=y_-y_,b_i=x_-x_i,c_i=x_iy_-x_y_i\)
我們需要使得\(\forall i\in[1,n]\)有\(a_0x+b_0+c_0
即\((a_0-a_i)x+(b_0-b_i)y+(c_0-c_i)<0\)
不難發現這樣的\((x,y)\)都在乙個半平面內
確切的講當\(b_0-b_i>0\)的時候,這樣的\((x,y)\)都在直線\((a_0-a_i)x+(b_0-b_i)y+(c_0-c_i)=0\)的下方;當\(b_0-b_i<0\)時,就在直線的上方
於是我們對得到的這\(n\)條限制以及凸包上原來的\(n\)條邊求乙個半平面交就好了,答案就是半平面交的面積除以原來凸包的面積
**
#include#define re register
const double eps=1e-6;
const int maxn=2e5+5;
int n,h,t,n,tot;
struct ptp[maxn];
struct linel[maxn],q[maxn];
inline int dcmp(double a,double b)
inline pt sec(const line &a,const line &b)
inline int cmp(const line &a,const line &b)
inline void half()
for(re int i=1;i<=tot;i++)
while(hwhile(h}inline void getabc(double &a,double &b,double &c,int i)
int main() ,nw.t=(pt);
else if(!dcmp(b,0)) nw.s=(pt),nw.t=(pt);
l[++n]=nw;
} half();q[t+1]=q[h];int cnt=0;
for(re int i=h;i<=t;i++) p[++cnt]=sec(q[i],q[i+1]);
p[cnt+1]=p[1];
for(re int i=1;i<=cnt;i++) ans+=fabs((p[i]-p[1])*(p[i+1]-p[1]));
printf("%.4lf\n",ans/sum);return 0;
}
SCOI2015 小凸想跑步
半平面交 題目要求求出讓 delta pp 0p 1 在所有形成的三角形中面積最小 那麼可以考慮對於點 p x y p p 一定有 x x 1 y y 1 times x 0 x 1 y 0 y 1 x x i y y i times x x i y y i 那麼把式子化開就可以得到若干 ax by...
SCOI2015 小凸想跑步 解題報告
最開始以為和多邊形的重心有關,後來發現多邊形的重心沒啥好玩的性質 實際上你把面積小於的不等式列出來,發現是一次的,那麼就可以半平面交了 code include include include define vector point const int n 2e5 10 const double e...
省選專練SCOI2015小凸想跑步
終於快把scoi練完了。毒瘤題這個題難點不在半平面交,在於推導 其次精度問題 eps 和inf 取值需謹慎。大了會丟精度,小了會炸精度。接著得開long double 於是流輸出。includeusing namespace std define double long double const d...