一遇到数学题和计算几何题我就要调半天……
玛雅,我真是太弱了……
基本思路很简单,先上凸包,然后矩形与凸包一边重合,然后旋转卡壳即可
然而我没怎么写过计算几何题,一开始写的各种囧,后来看了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.