zoukankan      html  css  js  c++  java
  • BZOJ 1043 圆弧覆盖

    为按照极角,转化为线段覆盖问题。

    这题有个特别混蛋的trick,就是后掉落的把先掉落的完全覆盖了,我就没考虑这个,无限wa啊!!

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <vector>
      8 
      9 #define N 1111
     10 #define PI 3.14159265358979323846
     11 #define EPS 1e-7
     12 
     13 using namespace std;
     14 
     15 struct PO
     16 {
     17     double x,y,r;
     18     void prt() {printf("%lf     %lf\n",x,y);}
     19 }p[N];
     20 
     21 struct V
     22 {
     23     int fg; double f;
     24 };
     25 vector<V> v[N];
     26 
     27 int n;
     28 double sum,ans;
     29 bool vis[N];
     30 
     31 inline int dc(double x)
     32 {
     33     if(x>EPS) return 1;
     34     else if(x<-EPS) return -1;
     35     return 0;
     36 }
     37 
     38 inline bool cmp(const V &a,const V &b)
     39 {
     40     if(a.f==b.f) return a.fg>b.fg;
     41     return a.f<b.f;
     42 }
     43 
     44 inline PO operator -(PO a,PO b)
     45 {
     46     a.x-=b.x; a.y-=b.y;
     47     return a;
     48 }
     49 
     50 inline PO operator +(PO a,PO b)
     51 {
     52     a.x+=b.x; a.y+=b.y;
     53     return a;
     54 }
     55 
     56 inline PO operator *(PO a,double k)
     57 {
     58     a.x*=k; a.y*=k;
     59     return a;
     60 }
     61 
     62 inline PO operator /(PO a,double k)
     63 {
     64     a.x/=k; a.y/=k;
     65     return a;
     66 }
     67 
     68 inline double getlen(const PO &a)
     69 {
     70     return sqrt(a.x*a.x+a.y*a.y);
     71 }
     72 
     73 inline double getdis(const PO &a,const PO &b)
     74 {
     75     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     76 }
     77 
     78 inline PO rotate(const PO &a,double sss,double ccc)
     79 {
     80     PO rt;
     81     rt.x=a.x*ccc-a.y*sss;
     82     rt.y=a.x*sss+a.y*ccc;
     83     return rt;
     84 }
     85 
     86 inline void read()
     87 {
     88     scanf("%d",&n);
     89     for(int i=1;i<=n;i++)
     90         scanf("%lf%lf%lf",&p[i].r,&p[i].x,&p[i].y);
     91 }
     92 
     93 inline void getcpoint(const PO &a,const PO &b,PO &s,PO &t)//求圆的交点,a的逆时针方向的弧上的点 
     94 {
     95     PO ab=b-a;
     96     double d=getlen(ab);
     97     double ccc=(b.r*b.r-d*d-a.r*a.r)/(-2.0*a.r*d);
     98     double sss=sqrt(1.0-ccc*ccc);
     99     ab=ab/d*a.r;
    100     s=a+rotate(ab,-sss,ccc);
    101     t=a+rotate(ab,sss,ccc);
    102 }
    103 
    104 inline void go()
    105 {
    106     PO a,b; V c;
    107     double f1,f2;
    108     for(int i=1;i<=n;i++)
    109         for(int j=i+1;j<=n;j++)
    110         {
    111             double dis=getdis(p[i],p[j]);
    112             if(dis+1e-10>p[i].r+p[j].r || p[j].r+1e-10<p[i].r&&dis-1e-10<p[i].r-p[j].r) continue;
    113             if(p[i].r<p[j].r+1e-10&&dis-1e-10<p[j].r-p[i].r) {vis[i]=true; break;}
    114             getcpoint(p[i],p[j],a,b);
    115             f1=atan2(a.y-p[i].y,a.x-p[i].x);
    116             f2=atan2(b.y-p[i].y,b.x-p[i].x);
    117             if(f1>f2)
    118             {
    119                 c.f=f1; c.fg=1; v[i].push_back(c);
    120                 c.f=PI; c.fg=-1; v[i].push_back(c);
    121                 c.f=-PI; c.fg=1; v[i].push_back(c);
    122                 c.f=f2; c.fg=-1; v[i].push_back(c);
    123             }
    124             else
    125             {
    126                 c.f=f1; c.fg=1; v[i].push_back(c);
    127                 c.f=f2; c.fg=-1; v[i].push_back(c);
    128             }
    129         }
    130     for(int i=1;i<=n;i++)
    131     {
    132         if(vis[i]) continue;
    133         sum+=2*PI*p[i].r;
    134         sort(v[i].begin(),v[i].end(),cmp);
    135         int tmp=0; double last;
    136         for(int j=0;j<v[i].size();j++)
    137         {
    138             tmp+=v[i][j].fg;
    139             if(tmp==1&&v[i][j].fg==1) last=v[i][j].f;
    140             else if(tmp==0&&v[i][j].fg==-1) ans+=(v[i][j].f-last)*p[i].r;
    141         }
    142     }
    143     printf("%.3lf\n",sum-ans);
    144 }
    145 
    146 int main()
    147 {
    148     read(),go();
    149     return 0;
    150 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    vue-cli脚手架工具构建&初始化vue项目
    2020/05/17 Github加速-DNS配置
    同时将本地git仓库提交到gitee和github
    git远程仓库在本地看不到&push 到远程仓库失败的解决方案
    stylus的使用-变量和函数
    webpack使用4-HRM热替换&SourceMap&解析es语法
    webpack使用3-plugin插件的使用
    webpack使用2-常用的几个loader的使用
    webpack基本使用
    spring框架里面的注入?
  • 原文地址:https://www.cnblogs.com/proverbs/p/2956762.html
Copyright © 2011-2022 走看看