如果发现广告等破坏行为,请尽量将条目恢复到较早的版本而不是把相应内容直接删除,谢谢合作。
URAL/1043
来自"NOCOW"
< URAL
他给了圆弧的三个点,可以求出圆心和半径,分别求出圆上,最下,最上,最左,最右的坐标,判断这四个坐标是否在给的圆弧上,如果在则更新答案的最大值最小值即可(为什么只要这四个点去更新,按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.