一遇到数学题和计算几何题我就要调半天……

玛雅,我真是太弱了……

基本思路很简单,先上凸包,然后矩形与凸包一边重合,然后旋转卡壳即可

然而我没怎么写过计算几何题,一开始写的各种囧,后来看了hzwer的写法才写得正常一些

一开始写囧,是找矩形的左右边界,用勾股定理算的,囧得不行;

后来发现可以用点积来判断,点积的几何意义:向量A在向量B上投影的长度*向量B的长度

然后就很好做了

  1 const eps=1e-8;
  2 type point=record
  3        x,y:double;
  4      end;
  5 
  6 var a:array[0..50010] of point;
  7     q:array[0..50010] of longint;
  8     p:array[0..4] of point;
  9     n,f1,f2,h,r,t,k,i:longint;
 10     tmp,ans,d,l,l1,l2:double;
 11 
 12 procedure swap(var a,b:point);
 13   var c:point;
 14   begin
 15     c:=a;
 16     a:=b;
 17     b:=c;
 18   end;
 19 
 20 function cmp(a,b:point):boolean;
 21   begin
 22     if abs(a.y-b.y)<eps then exit(a.x<b.x);
 23     exit(a.y<b.y);
 24   end;
 25 
 26 function cross(i,j,k,p:longint):double;
 27   begin
 28     exit((a[i].x-a[j].x)*(a[k].y-a[p].y)-(a[i].y-a[j].y)*(a[k].x-a[p].x));
 29   end;
 30 
 31 procedure sort(l,r:longint);
 32   var i,j:longint;
 33       x:point;
 34   begin
 35     i:=l;
 36     j:=r;
 37     x:=a[(l+r) shr 1];
 38     repeat
 39       while cmp(a[i],x) do inc(i);
 40       while cmp(x,a[j]) do dec(j);
 41       if not(i>j) then
 42       begin
 43         swap(a[i],a[j]);
 44         inc(i);
 45         dec(j);
 46       end;
 47     until i>j;
 48     if l<j then sort(l,j);
 49     if i<r then sort(i,r);
 50   end;
 51 
 52 function dis(a,b:point):double;
 53   begin
 54     exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)));
 55   end;
 56 
 57 function mul(i,j,p,q:longint):double;
 58   begin
 59     exit((a[i].x-a[j].x)*(a[p].x-a[q].x)+(a[i].y-a[j].y)*(a[p].y-a[q].y));
 60   end;
 61 
 62 begin
 63   readln(n);
 64   for i:=1 to n do
 65     readln(a[i].x,a[i].y);
 66   sort(1,n);
 67   ans:=1e15;
 68   t:=1;
 69   q[1]:=1;
 70   for i:=2 to n do
 71   begin
 72     while (t>1) and (cross(q[t],q[t-1],i,q[t-1])<eps) do dec(t);
 73     inc(t);
 74     q[t]:=i;
 75   end;
 76   k:=t;
 77   for i:=n-1 downto 1 do
 78   begin
 79     while (t>k) and (cross(q[t],q[t-1],i,q[t-1])<eps) do dec(t);
 80     inc(t);
 81     q[t]:=i;
 82   end;
 83 //  q[t+1]:=q[1];
 84 {  for i:=1 to t do
 85     writeln(a[q[i]].x,' ',a[q[i]].y);
 86   writeln(k); }
 87   k:=2;
 88   h:=2;
 89   r:=2;
 90   for i:=1 to t-1 do
 91   begin
 92     d:=dis(a[q[i]],a[q[i+1]]);
 93     while cross(q[i+1],q[i],q[k mod t+1],q[i])-cross(q[i+1],q[i],q[k],q[i])>-eps do k:=k mod t+1;
 94     while (mul(q[i+1],q[i],q[r mod t+1],q[i])-mul(q[i+1],q[i],q[r],q[i])>-eps) do r:=r mod t+1;
 95     if i=1 then h:=r;
 96     while (mul(q[i+1],q[i],q[h mod t+1],q[i])-mul(q[i+1],q[i],q[h],q[i])<eps) do h:=h mod t+1;
 97     l1:=mul(q[i+1],q[i],q[h],q[i])/d;
 98     l2:=mul(q[i+1],q[i],q[r],q[i])/d;
 99     l:=abs(cross(q[i+1],q[i],q[k],q[i]))/d;
100     tmp:=(l2-l1)*l;
101     if ans>tmp then
102     begin
103       ans:=tmp;
104      // writeln(tmp,' ',a[q[i]].x,' ',a[q[i]].y,' ',l2/d);
105       p[0].x:=a[q[i]].x+(a[q[i+1]].x-a[q[i]].x)*l2/d;
106       p[0].y:=a[q[i]].y+(a[q[i+1]].y-a[q[i]].y)*l2/d;
107      // writeln(p[0].x,' ',p[0].y);
108       p[1].x:=p[0].x+(a[q[r]].x-p[0].x)*l/dis(p[0],a[q[r]]);
109       p[1].y:=p[0].y+(a[q[r]].y-p[0].y)*l/dis(p[0],a[q[r]]);
110       p[2].x:=p[1].x-(p[0].x-a[q[i]].x)*(l2-l1)/dis(p[0],a[q[i]]);
111       p[2].y:=p[1].y-(p[0].y-a[q[i]].y)*(l2-l1)/dis(p[0],a[q[i]]);
112       p[3].x:=p[2].x-(p[1].x-p[0].x);
113       p[3].y:=p[2].y-(p[1].y-p[0].y);
114     end;
115   end;
116   writeln(ans:0:5);
117   h:=0;
118   for i:=1 to 3 do
119     if cmp(p[i],p[h]) then h:=i;
120   for i:=0 to 3 do
121     writeln(p[(h+i) mod 4].x:0:5,' ',p[(h+i) mod 4].y:0:5);
122 end.
View Code

 

posted on 2015-06-04 20:30  acphile  阅读(162)  评论(0编辑  收藏  举报