zoukankan      html  css  js  c++  java
  • bzoj 4445 [SCOI2015] 小凸想跑步

    题目大意:一个凸包,随机一个点使得其与前两个点组成的面积比与其他相邻两个点组成的面积小的概率

    根据题意列方程,最后求n条直线的交的面积与原凸包面积的比值

      1 #include<bits/stdc++.h>
      2 #define maxn 100010
      3 #define eps 1e-10
      4 using namespace std;
      5 double ans,S1,S2;
      6 struct P{
      7     double x,y;
      8     P(double a=0,double b=0){x=a,y=b;}
      9 };
     10 struct L{
     11     P a,b;
     12     double ang;
     13 };
     14 int sgn(double x){
     15     return (x>eps)-(x<-eps);
     16 }
     17 P operator - (P a,P b){
     18     return P(a.x-b.x,a.y-b.y);
     19 }
     20 double operator * (P a,P b){
     21     return a.x*b.y-a.y*b.x;
     22 }
     23 bool operator < (L a,L b){
     24     if(sgn(a.ang-b.ang)!=0)return a.ang<b.ang;
     25     return (a.a-b.a)*a.b<0;
     26 }
     27 int n;
     28 P s[maxn];
     29 L l[maxn],q[maxn];P p[maxn];
     30 int h,r,tot,cnt;
     31 L get_line(P A,P B,P C,P D){
     32     L l;
     33     double a=-A.y-D.y+B.y+C.y;
     34     double b=-B.x-C.x+A.x+D.x;
     35     double c=-A.x*B.y-D.x*C.y+B.x*A.y+C.x*D.y;
     36     l.b=P(b,-a);
     37     if(sgn(a)!=0)l.a=P(-c/a,0);
     38     else l.a=P(0,-c/b);
     39     return l;
     40 }
     41 void get_line(){
     42     for(int i=2;i<=n;++i)
     43         l[++cnt]=get_line(s[1],s[2],s[i],s[i+1]);
     44     for(int i=1;i<=n;++i){
     45         l[++cnt].a=s[i];
     46         l[cnt].b=s[i+1]-s[i];
     47     }
     48     for(int i=1;i<=cnt;++i)
     49         l[i].ang=atan2(l[i].b.y,l[i].b.x);
     50 }
     51 P inter(L a,L b){
     52     P p=b.a-a.a;
     53     double t=(p*b.b)/(a.b*b.b);
     54     P ans;
     55     ans.x=a.a.x+a.b.x*t;
     56     ans.y=a.a.y+a.b.y*t;
     57     return ans;
     58 }
     59 bool jud(L a,L b,L c){
     60     P p=inter(a,b);
     61     return (p-c.a)*c.b>0;
     62 }
     63 void get_Point(){
     64     sort(l+1,l+cnt+1);tot=1;
     65     for(int i=2;i<=cnt;++i)
     66         if(sgn(l[i].ang-l[i-1].ang)!=0)
     67             l[++tot]=l[i];
     68     cnt=tot;tot=0,h=1;
     69     q[++r]=l[1];q[++r]=l[2];
     70     for(int i=3;i<=cnt;++i){
     71         if(sgn(q[r].b*q[r-1].b)==0)return;
     72         if(sgn(q[h].b*q[h+1].b)==0)return;
     73         while(h<r&&jud(q[r-1],q[r],l[i]))r--;
     74         while(h<r&&jud(q[h+1],q[h],l[i]))h++;
     75         q[++r]=l[i];
     76     }
     77     while(h<r&&jud(q[r-1],q[r],q[h]))r--;
     78     while(h<r&&jud(q[h+1],q[h],q[r]))h++;
     79     q[r+1]=q[h];
     80     for(int i=h;i<=r;++i)
     81         p[++tot]=inter(q[i],q[i+1]);
     82     p[++tot]=p[1];
     83 }
     84 double get_S(P a[],int cnt){
     85     double ans=0;
     86     if(cnt<3)return 0;
     87     for(int i=1;i<cnt;++i){
     88         ans+=a[i]*a[i+1];
     89     }
     90     ans=fabs(ans/2);
     91     return ans;
     92 }
     93 void init(){
     94     scanf("%d",&n);
     95     for(int i=1;i<=n;++i){
     96         int x,y;scanf("%d%d",&x,&y);
     97         s[i].x=x;s[i].y=y;
     98     }
     99     s[n+1]=s[1];
    100 }
    101 void work(){
    102     get_line();
    103     get_Point();
    104     S1=get_S(s,n+1);
    105     S2=get_S(p,tot);
    106     ans=S2/S1;
    107     printf("%.4lf",ans);
    108 }
    109 int main(){
    110     init();
    111     work();
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    [Leetcode] Flatten Binary Tree to Linked List
    [Leetcode] Letter Combinations of a Phone Number
    [Leetcode] Distinct Subsequences
    [Leetcode] Partition List
    [Leetcode] Reverse Linked List II
    [Leetcode] Swap Nodes in Pairs
    [Jobdu] 题目1391:顺时针打印矩阵
    [Jobdu] 题目1369:字符串的排列
    [Jobdu] 题目1283:第一个只出现一次的字符
    如何应用ML的建议-下
  • 原文地址:https://www.cnblogs.com/117208-/p/5361080.html
Copyright © 2011-2022 走看看