zoukankan      html  css  js  c++  java
  • bzoj1043

    每次做计算几何题都要做好久

    考虑每个圆对答案的贡献,也就是每个圆被后面圆覆盖还有多少

    可以把覆盖当成盖住一段弧度,看最后有多少没被覆盖

    这就相当于线段覆盖问题了,

    推推公式,算极角然后排序即可

    md,pascal算极角就是麻烦

      1 uses math;
      2 const pi=3.1415926535897932384626433832795;
      3       eps=1e-4;
      4 type node=record
      5        l,r:double;
      6      end;
      7 
      8 var q:array[0..2010] of node;
      9     x,y,r:array[0..2010] of double;
     10     t,j,i,n:longint;
     11     ans:double;
     12 
     13 function dis(i,j:longint):double;
     14   begin
     15     exit(sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j])));
     16   end;
     17 
     18 function have(i,j:longint):boolean;
     19   begin
     20     exit(r[j]-r[i]>=dis(i,j));
     21   end;
     22 
     23 procedure swap(var a,b:node);
     24   var c:node;
     25   begin
     26     c:=a;
     27     a:=b;
     28     b:=c;
     29   end;
     30 
     31 function get(x,y:double):double;
     32   begin
     33     if x=0 then
     34     begin
     35       if y>0 then exit(pi/2)
     36       else exit(-pi/2);
     37     end;
     38     get:=arctan(y/x);
     39     if (x<0) then get:=get+pi;
     40   end;
     41 
     42 procedure sort(l,r:longint);
     43   var i,j:longint;
     44       x:double;
     45   begin
     46     i:=l;
     47     j:=r;
     48     x:=q[(l+r) shr 1].l;
     49     repeat
     50       while q[i].l<x do inc(i);
     51       while x<q[j].l do dec(j);
     52       if not(i>j) then
     53       begin
     54         swap(q[i],q[j]);
     55         inc(i);
     56         dec(j);
     57       end;
     58     until i>j;
     59     if l<j then sort(l,j);
     60     if i<r then sort(i,r);
     61   end;
     62 
     63 function cal(j:longint):double;
     64   var i:longint;
     65       d,now,l,z,an:double;
     66   begin
     67     for i:=j+1 to n do
     68       if have(j,i) then exit(0);
     69     t:=0;
     70     for i:=j+1 to n do
     71     begin
     72       d:=dis(i,j);
     73       if not have(i,j) and (r[j]+r[i]>d) then
     74       begin
     75         inc(t);
     76         an:=get(x[i]-x[j],y[i]-y[j]);
     77         l:=(sqr(r[j])-sqr(r[i])+sqr(d))/(2*d);
     78         z:=arccos(l/r[j]);
     79         q[t].l:=an-z;
     80         q[t].r:=an+z;
     81      //   writeln(an,' ',z,' ',i,' ',x[i]-x[j],' ',y[i]-y[j]);
     82      //   readln;
     83       end;
     84     end;
     85     for i:=1 to t do
     86     begin
     87       if q[i].l>2*pi then q[i].l:=q[i].l-2*pi;
     88       if q[i].r>2*pi then q[i].r:=q[i].r-2*pi;
     89       if q[i].l<0 then q[i].l:=q[i].l+2*pi;
     90       if q[i].r<0 then q[i].r:=q[i].r+2*pi;
     91       if q[i].l>q[i].r then
     92       begin
     93         inc(t);
     94         q[t].l:=0;
     95         q[t].r:=q[i].r;
     96         q[i].r:=2*pi;
     97       end;
     98     end;
     99     sort(1,t);
    100     cal:=0;
    101     now:=0;
    102     for i:=1 to t do
    103       if q[i].l>now then
    104       begin
    105         cal:=cal+(q[i].l-now);
    106         now:=q[i].r;
    107       end
    108       else if now<q[i].r then now:=q[i].r;
    109 
    110     cal:=cal+2*pi-now;
    111     if cal<0 then cal:=0;
    112     cal:=cal*r[j];
    113   end;
    114 
    115 begin
    116   readln(n);
    117   for i:=1 to n do
    118     readln(r[i],x[i],y[i]);
    119 
    120   for i:=1 to n do
    121     ans:=ans+cal(i);
    122 
    123   writeln(ans:0:3);
    124 end.
    View Code
  • 相关阅读:
    python第三周练习
    python第一周作业
    SQLite3—数据库的学习—python
    python实现跳一跳辅助的实验报告
    Python——自己的第一个网页(文件的使用)
    第一次爬虫和测试
    numpy和matplotlib使用
    Python作业———预测球队比赛成绩
    PIL库的学习
    Pytho作业——Jieba库的使用和好玩的词云
  • 原文地址:https://www.cnblogs.com/phile/p/4609517.html
Copyright © 2011-2022 走看看