zoukankan      html  css  js  c++  java
  • 半平面交

    题解:

    把n凸边型转化为n条边后

    等价于给出k条直线,让你求直线左边区域的交

    然后大概步骤是

    首先要给边排序,按照极角从-pai开始逆时针排序

    另外平行边我们只需要保留那条约束条件更强的

    维护一个双端队列

    加点之后判断$(p[h],p[h+1])$的交点$(p[t-1],p[t])$的交点是否在当前直线右边

    如果是就不断循环暴力弹

    做完之后由于把最后的平面都直接加进来了,所以还要删除没用的

    就是$(p[t],p[t-1])$在$p[h]$右边的

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    const int N=2e5;
    const double eps=1e-6;
    struct point
    {
      double a,b;
      point operator +(point o)
      {
        return (point){a+o.a,b+o.b};
      }
      point operator -(point o)
      {
        return (point){a-o.a,b-o.b};
      }
      point operator *(double x)
      {
        return (point){x*a,x*b};
      }
      point operator /(double x)
      {
        return (point){a/x,b/x};
      }
      double operator *(point x)
      {
        return x.a*a+x.b*b;
      }
      double operator ^(point x)
      {
        return a*x.b-x.a*b;
      }
    }p[N],a[N];
    struct line
    {
      point a,b;
    }s[N],l[N];
    int tt,st,m;
    IL bool pd(line x,line y)
    {
      double tt=x.b^y.b;
      return (tt>0||(tt==0&&(x.b^(y.a-x.a))>0));
    }
    bool cmp(line x,line y)
    {
      if (x.b.b==0&&y.b.b==0) return x.b.a<y.b.a;
      if ((x.b.b<=0&&y.b.b<=0)||(x.b.b>0&&y.b.b>0)) return pd(x,y);
      return x.b.b<y.b.b;
    }
    bool pd2(line x,line y)
    {
      return x.b^y.b;
    }
    bool pd3(point x,line y)
    {
      return (y.b^(x-y.a))<=0;
    }
    point get_j(line x,line y)
    {
      double k=(y.a-x.a)^y.b/(x.b^y.b);
      return x.a+(x.b*k);
    }
    IL double area(point a,point b,point c)
    {
      return (abs)((b-a)^(c-a));
    }
    void solve()
    {
      sort(l+1,l+m+1,cmp);
      int tp=0;
      rep(i,1,m)
      {
        if(i==1||pd2(l[i],l[i-1])) tp++;
        l[tp]=l[i];
      }
      m=tp;
      int h=1,t=2;
      s[1]=l[1],s[2]=l[2];
      rep(i,3,m)
      {
        while (h<t&&pd3(get_j(s[t],s[t-1]),l[i])) t--;
        while (h<t&&pd3(get_j(s[h],s[h+1]),l[i])) h++;
        s[++t]=l[i];
      }
      while (h<t&&pd3(get_j(s[t],s[t-1]),s[h])) t--;
      if (t-h<=1) {printf("0.000"); return;}
      tp=0;
      s[h-1]=s[t];
      rep(i,h,t) a[++tp]=get_j(s[i],s[i-1]);
      double ans=0;
      rep(i,3,tp) ans+=area(a[1],a[i-1],a[i])/2;
      printf("%.3lf",ans);
    }
    int main()
    {
      ios::sync_with_stdio(false);
      int tt;
      cin>>tt;
      int n=0;
      while (tt--)
      {
        int k;
        cin>>k;
        int st=n+1;
        while (k--)
        {
          double x,y;
          cin>>x>>y;
          p[++n]=(point){x,y};
          if (n>st) l[++m]=(line){p[n-1],p[n]-p[n-1]};
        }
        l[++m]=(line){p[n],p[st]-p[n]};
      }
      solve();
      return 0; 
    }
  • 相关阅读:
    DataGrid 样式
    MVC调用部分视图PartialView
    JavaScript/jQuery判断变量是否是undefined
    form表单只单个input框按回车键页面会自动刷新
    无法使用前导 .. 在顶级目录上退出
    Response.Redirect:正在中止线程
    图片压缩是出现白边如何去除
    C#.Net调试时调无法“编辑并继续”
    TimeSpan时间间隔
    拒绝了对对象 'sp_OACreate' (数据库 'mssqlsystemresource',架构 'sys')的 EXECUTE权限
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/10206388.html
Copyright © 2011-2022 走看看