如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。

URAL/1043

来自"NOCOW"

跳转到: 导航, 搜索

他给了圆弧的三个点,可以求出圆心和半径,分别求出圆上,最下,最上,最左,最右的坐标,判断这四个坐标是否在给的圆弧上,如果在则更新答案的最大值最小值即可(为什么只要这四个点去更新,按X你可以把圆弧分成两个单调区间,按Y你也可以把圆弧分成两个单调区间,从这方面想就不难理解了).

其实我也看了Maigo的代码才写出来的

{study from a cow}
program cao;
const
  eps=1e-7;
 
var
  a,b,c,d,e,f,g,h,i,j,k,l,n,m,x1,x2,x3,y1,y2,y3,maxx,maxy,minx,miny:longint;
  x,y,r,a1,a2,a3:extended;
  inner:boolean;
 
function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;
 
function min(a,b:longint):longint;
begin
  if a>b then exit(b) else exit(a);
end;
 
procedure work_linear_equation(var x,y:extended;a1,b1,c1,a2,b2,c2:longint);
begin
  x:=(c1*b2-c2*b1)/(a1*b2-a2*b1);
  y:=(c1*a2-c2*a1)/(b1*a2-b2*a1);
end;
 
function ceil(x:extended):longint;
var
  t:longint;
begin
  if x>0 then t:=trunc(x+1-eps) else t:=trunc(x-1-eps);
  if t<x then inc(t);
  exit(t);
end;
 
function floor(x:extended):longint;
var
  t:longint;
begin
  t:=trunc(x+eps);
  if t>x then dec(t);
  exit(t);
end;
 
function get_angle(x1,y1:longint):extended;
var
  angle:extended;
begin
  if x1=x then
    if y1>y then angle:=pi*0.5 else angle:=pi*1.5
  else if x1>x then
    angle:=arctan((y1-y)/(x1-x))
  else
    angle:=arctan((y1-y)/(x1-x))+pi;
  if angle<0 then angle:=angle+pi*2;
  exit(angle);
end;
 
function on_arc(angle:extended):boolean;
begin
  on_arc:=not(((a3-a1)*(a3-a2)<=0)xor((angle-a1)*(angle-a2)<=0));
end;
 
begin
  read(x1,y1,x2,y2,x3,y3);
  work_linear_equation(x,y,2*(x2-x1),2*(y2-y1),-(x1-x2)*(x1+x2)-(y1-y2)*(y1+y2),2*(x3-x1),2*(y3-y1),-(x1-x3)*(x1+x3)-(y1-y3)*(y1+y3));
  r:=sqrt(sqr(x1-x)+sqr(y1-y));
  a1:=get_angle(x1,y1);
  a2:=get_angle(x2,y2);
  a3:=get_angle(x3,y3);
  if on_arc(0) then maxx:=ceil(x+r) else maxx:=ceil(max(x1,x2));
  if on_arc(pi*0.5) then maxy:=ceil(y+r) else maxy:=ceil(max(y1,y2));
  if on_arc(pi) then minx:=floor(x-r) else minx:=floor(min(x1,x2));
  if on_arc(pi*1.5) then miny:=floor(y-r) else miny:=floor(min(y1,y2));
  writeln((maxx-minx)*(maxy-miny));
end.



http://www.cgang.tk by cgangee 好像数据加强了,上面的代码AC不了 查错查了半天,才怀疑弧可能在地板外。。。 代码也写的出奇的恶心

type arr=record x,y:extended; end;
 
var i,j,k,n,l:longint;
    a:array[1..4] of arr;
    x,y,r,m:extended;
    min_x,min_y,max_x,max_y:longint;
    p,q:arr;
    ii,nn:longint;
 
procedure get_x_y_r;
var g:array[1..2,1..3]of extended;
    f:array[1..2]of longint;
    ans:array[1..2]of extended;
    p,q:extended;
 
 
begin
     for i:=1 to 2 do
     begin
          g[i,1]:=2*(a[3].x-a[i].x);
          g[i,2]:=2*(a[3].y-a[i].y);
          g[i,3]:=sqr(a[i].x)+sqr(a[i].y)-sqr(a[3].x)-sqr(a[3].y);
     end;
     for i:=1 to 2 do
     begin
          for j:=1 to i-1 do
          begin
               if g[i,f[j]]=0 then continue;
               p:=g[i,f[j]]; q:=g[j,f[j]];
               for k:=1 to 3 do g[i,k]:=g[i,k]*q-g[j,k]*p;
          end;
          for j:=1 to 2 do if g[i,j]<>0 then
          begin f[i]:=j; break; end;
     end;
     ans[f[2]]:=-1*g[2,3]/g[2,f[2]];
     ans[f[1]]:=-1*(g[1,3]+g[1,f[2]]*ans[f[2]])/g[1,f[1]];
     x:=ans[1]; y:=ans[2];
     r:=sqrt(sqr(a[1].x-x)+sqr(a[1].y-y));
end;
 
procedure update(i,j:longint);
 
  function min(i,j:longint):longint;
  begin if i<j then exit(i); exit(j); end;
 
  function max(i,j:longint):longint;
  begin if i>j then exit(i); exit(j); end;
 
begin
     min_x:=min(min_x,i);
     min_y:=min(min_y,j);
     max_x:=max(max_x,i);
     max_y:=max(max_y,j);
end;
 
function get(a,b:arr):arr;
begin
     get.x:=b.x-a.x;
     get.y:=b.y-a.y;
end;
 
function fork(a,b:arr):extended;
begin fork:=a.x*b.y-a.y*b.x; end;
 
function f(k:extended):longint;
var t:longint;
begin
     t:=trunc(k);
     if (k>0)and(k<>t) then inc(t);
     exit(t);
end;
 
function g(k:extended):longint;
var t:longint;
begin
     t:=trunc(k);
     if (k<0)and(k<>t) then dec(t);
     exit(t);
end;
 
procedure adj;
begin
     if a[4].x<-1000 then a[4].x:=-1000;
     if a[4].y<-1000 then a[4].y:=-1000;
     if a[4].x>1000 then a[4].x:=1000;
     if a[4].y>1000 then a[4].y:=1000;
end;
 
begin
 
     for i:=1 to 3 do read(a[i].x,a[i].y);
     get_x_y_r;
     min_x:=round(a[1].x);
     min_y:=round(a[1].y);
     max_x:=round(a[1].x);
     max_y:=round(a[1].y);
     for i:=2 to 3 do update(round(a[i].x),round(a[i].y));
     p:=get(a[1],a[2]);
     q:=get(a[1],a[3]);
     m:=fork(p,q);
 
     a[4].x:=x;
     a[4].y:=y+r;
     adj;
     if m*fork(p,get(a[1],a[4]))>=0 then update(round(a[4].x),f(a[4].y));
 
     a[4].x:=x;
     a[4].y:=y-r;
     adj;
     if m*fork(p,get(a[1],a[4]))>=0 then update(round(a[4].x),g(a[4].y));
 
     a[4].x:=x-r;
     a[4].y:=y;
     adj;
     if m*fork(p,get(a[1],a[4]))>=0 then update(g(a[4].x),round(a[4].y));
 
     a[4].x:=x+r;
     a[4].y:=y;
     adj;
     if m*fork(p,get(a[1],a[4]))>=0 then update(f(a[4].x),round(a[4].y));
 
     writeln((max_x-min_x)*(max_y-min_y));
 
end.
个人工具