USACO 6.4.2 Electric Fences 数学+暴力

来源:互联网 发布:如何编写抢购软件 编辑:程序博客网 时间:2024/06/07 10:33

嗯我们首先注意到这题的数据非常小,于是就枚举范围内的每一个整数点,找到最优点(x,y)后枚举(x-1到x+1,y-1到y+1)并把精度往后挪一位,再找到最优的点并输出就好了。

至于判断一个点到某条线段的距离,要分两种情况:一种是点在该直线的投影在这条线段上,那就用矢量叉积算出三角形的面积再算出高就好了;另一种则是选择该点到两个端点中距离较小的一个。

代码:

{ID: ymwbegi1PROG: fence3LANG: PASCAL} var  p,q,n,i,j,k:longint;  ansx,ansy,i1,j1,mins,s:real;  x1,y1,x2,y2,l:array[1..150] of longint;procedure exchange(var x,y:longint);var  t:longint;begin  t:=x;  x:=y;  y:=t;end;function min(x,y:real):real;begin  if x<y then exit(x)         else exit(y);end;begin  assign(input,'fence3.in');  assign(output,'fence3.out');  reset(input);  rewrite(output);  readln(n);  for i:=1 to n do  begin    readln(x1[i],y1[i],x2[i],y2[i]);    if x1[i]=x2[i]      then l[i]:=abs(y1[i]-y2[i])      else l[i]:=abs(x1[i]-x2[i]);    if x1[i]>x2[i] then exchange(x1[i],x2[i]);    if y1[i]>y2[i] then exchange(y1[i],y2[i]);  end;  mins:=maxlongint;  for i:=0 to 100 do  begin    s:=0;    for j:=0 to 100 do    begin      s:=0;      for k:=1 to n do        if (x1[k]<=i)and(x2[k]>=i)and(x1[k]<>x2[k])or(y1[k]<>y2[k])and(y1[k]<=j)and(y2[k]>=j)          then s:=s+abs((x1[k]-i)*(y2[k]-j)-(x2[k]-i)*(y1[k]-j))/l[k]          else s:=s+min(sqrt(sqr(x1[k]-i)+sqr(y1[k]-j)),sqrt(sqr(x2[k]-i)+sqr(y2[k]-j)));      if s<mins then      begin        mins:=s;        p:=i;        q:=j;      end;    end;  end;  mins:=maxlongint;  for i:=(p-1)*10 to (p+1)*10 do    for j:=(q-1)*10 to (q+1)*10 do    begin      s:=0;      i1:=i/10;      j1:=j/10;      for k:=1 to n do        if (x1[k]<=i1)and(x2[k]>=i1)and(x1[k]<>x2[k])or(y1[k]<>y2[k])and(y1[k]<=j1)and(y2[k]>=j1)          then s:=s+abs((x1[k]-i1)*(y2[k]-j1)-(x2[k]-i1)*(y1[k]-j1))/l[k]          else s:=s+min(sqrt(sqr(x1[k]-i1)+sqr(y1[k]-j1)),sqrt(sqr(x2[k]-i1)+sqr(y2[k]-j1)));      if s<mins then      begin        ansx:=i1;        ansy:=j1;        mins:=s;      end;    end;  writeln(ansx:0:1,' ',ansy:0:1,' ',mins:0:1);  close(input);  close(output);end.


0 0