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

玛雅,我真是太弱了……

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

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

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

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

然后就很好做了

 const eps=1e-8;
 type point=record
        x,y:double;
      end;

 ..] of point;
     q:..] of longint;
     p:..] of point;
     n,f1,f2,h,r,t,k,i:longint;
     tmp,ans,d,l,l1,l2:double;

 procedure swap(var a,b:point);
   var c:point;
   begin
     c:=a;
     a:=b;
     b:=c;
   end;

 function cmp(a,b:point):boolean;
   begin
     if abs(a.y-b.y)<eps then exit(a.x<b.x);
     exit(a.y<b.y);
   end;

 function cross(i,j,k,p:longint):double;
   begin
     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));
   end;

 procedure sort(l,r:longint);
   var i,j:longint;
       x:point;
   begin
     i:=l;
     j:=r;
     x:=a[(l+r) shr ];
     repeat
       while cmp(a[i],x) do inc(i);
       while cmp(x,a[j]) do dec(j);
       if not(i>j) then
       begin
         swap(a[i],a[j]);
         inc(i);
         dec(j);
       end;
     until i>j;
     if l<j then sort(l,j);
     if i<r then sort(i,r);
   end;

 function dis(a,b:point):double;
   begin
     exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)));
   end;

 function mul(i,j,p,q:longint):double;
   begin
     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));
   end;

 begin
   readln(n);
    to n do
     readln(a[i].x,a[i].y);
   sort(,n);
   ans:=1e15;
   t:=;
   q[]:=;
    to n do
   begin
     ) ],i,q[t-])<eps) do dec(t);
     inc(t);
     q[t]:=i;
   end;
   k:=t;
     do
   begin
     ],i,q[t-])<eps) do dec(t);
     inc(t);
     q[t]:=i;
   end;
 //  q[t+]:=q[];
 {  for i:=1 to t do
     writeln(a[q[i]].x,' ',a[q[i]].y);
   writeln(k); }
   k:=;
   h:=;
   r:=;
     do
   begin
     d:=dis(a[q[i]],a[q[i+]]);
     ],q[i],q[k ],q[i])-cross(q[i+],q[i],q[k],q[i])>-eps ;
     ],q[i],q[r ],q[i])-mul(q[i+],q[i],q[r],q[i])>-eps) ;
      then h:=r;
     ],q[i],q[h ],q[i])-mul(q[i+],q[i],q[h],q[i])<eps) ;
     l1:=mul(q[i+],q[i],q[h],q[i])/d;
     l2:=mul(q[i+],q[i],q[r],q[i])/d;
     l:=abs(cross(q[i+],q[i],q[k],q[i]))/d;
     tmp:=(l2-l1)*l;
     if ans>tmp then
     begin
       ans:=tmp;
      // writeln(tmp,' ',a[q[i]].x,' ',a[q[i]].y,' ',l2/d);
       p[].x:=a[q[i]].x+(a[q[i+]].x-a[q[i]].x)*l2/d;
       p[].y:=a[q[i]].y+(a[q[i+]].y-a[q[i]].y)*l2/d;
      // writeln(p[].x,].y);
       p[].x:=p[].x+(a[q[r]].x-p[].x)*l/dis(p[],a[q[r]]);
       p[].y:=p[].y+(a[q[r]].y-p[].y)*l/dis(p[],a[q[r]]);
       p[].x:=p[].x-(p[].x-a[q[i]].x)*(l2-l1)/dis(p[],a[q[i]]);
       p[].y:=p[].y-(p[].y-a[q[i]].y)*(l2-l1)/dis(p[],a[q[i]]);
       p[].x:=p[].x-(p[].x-p[].x);
       p[].y:=p[].y-(p[].y-p[].y);
     end;
   end;
   writeln(ans::);
   h:=;
     do
     if cmp(p[i],p[h]) then h:=i;
     do
     writeln(p[(h+i) ].x::,].y::);
 end.

bzoj1185的更多相关文章

  1. 【BZOJ1185】[HNOI2007]最小矩形覆盖(凸包,旋转卡壳)

    [BZOJ1185][HNOI2007]最小矩形覆盖(凸包,旋转卡壳) 题面 BZOJ 洛谷 题解 最小的矩形一定存在一条边在凸包上,那么枚举这条边,我们还差三个点,即距离当前边的最远点,以及做这条边 ...

  2. BZOJ1185 [HNOI2007]最小矩形覆盖 【旋转卡壳】

    题目链接 BZOJ1185 题解 最小矩形一定有一条边在凸包上,枚举这条边,然后旋转卡壳维护另外三个端点即可 计算几何细节极多 维护另外三个端点尽量不在这条边上,意味着左端点尽量靠后,右端点尽量靠前, ...

  3. BZOJ1185 : [HNOI2007]最小矩形覆盖

    求出凸包后,矩形的一条边一定与凸包的某条边重合. 枚举每条边,求出离它最远的点和离它最左最右的点,因为那三个点是单调变化的,所以复杂度为$O(n)$. 注意精度. #include<cstdio ...

  4. 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1945  Solve ...

  5. BZOJ1185 HNOI2007 最小矩形覆盖 凸包、旋转卡壳

    传送门 首先,肯定只有凸包上的点会限制这个矩形,所以建立凸包. 然后可以知道,矩形上一定有一条边与凸包上的边重合,否则可以转一下使得它重合,答案会更小. 于是沿着凸包枚举这一条边,通过旋转卡壳找到离这 ...

  6. bzoj千题计划209:bzoj1185: [HNOI2007]最小矩形覆盖

    http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解去看它 http://www.cnblogs.com/TheRoadToTheGold/p ...

  7. 2018.10.18 bzoj1185: [HNOI2007]最小矩形覆盖(旋转卡壳)

    传送门 不难看出最后的矩形一定有一条边与凸包某条边重合. 因此先求出凸包,然后旋转卡壳求出当前最小矩形面积更新答案. 代码: #include<bits/stdc++.h> #define ...

  8. [BZOJ1185][HNOI2007]最小矩形覆盖-[凸包+旋转卡壳]

    Description 传送门 Solution 感性理解一下,最小矩形一定是由一条边和凸包上的边重合的. 然后它就是模板题了..然而真的好难调,小于大于动不动就打错. Code #include&l ...

  9. [HNOI2007][BZOJ1185] 最小矩形覆盖 [凸包+旋转卡壳]

    题面 BZOJ题面 前置芝士 建议先学习向量相关的计算几何基础 计算几何基础戳这里 思路 用这道题学习一下凸包和旋转卡壳 首先是凸包部分 凸包 求凸包用的算法是graham算法 算法流程如下: 找到$ ...

随机推荐

  1. 用遗传算法GA改进CloudSim自带的资源调度策略(2)

    遗传算法GA的核心代码实现: 最核心: private static ArrayList<int[]> GA(ArrayList<int[]> pop,int gmax,dou ...

  2. 获取WIFI的SSID和本机IP

    1.获取WIFI的SSID 引入库 #import <SystemConfiguration/CaptiveNetwork.h> ..... ..... // WIFI的名字 + (NSS ...

  3. Unitils集成DBUnit、Spring-单元测试

    Unitils集成DBUnit.Spring-单元测试 1.maven-pom文件中引入相关jar包 <!-- Unitils -dbunit.Spring --> <depende ...

  4. C#的async和await

    C# 5.0中引入了async 和 await.这两个关键字可以让你更方便的写出异步代码. 看个例子: public class MyClass { public MyClass() { Displa ...

  5. ARC以及MRC中setter方法

    ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下A ...

  6. BASE2(matlab)

    %{ // %} clc % linspace(3,5) 3到5 分成100 default %{ a=1 b=2 str = [num2str(a),'+',num2str(b)] eval(str ...

  7. 浅谈C10K问题

    在大型的APP中进行高并发的访问,淘宝,支付宝,微信,QQ,等 C10K问题:高并发的进行访问 C10K问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往 是非线性的.举个例子: ...

  8. linux下创建用户组与用户 只能访问指定目录的方法 以及FTP用户配置详解

    VSFTPD 安装: -- 查看是否已经安装 VSftpd: rpm -qa | grep vsftp yum install -y vsftpd groupadd ftpuser #创建ftpuse ...

  9. Spark application注册master机制

    直接上Master类的代码: case RegisterApplication(description) => { if (state == RecoveryState.STANDBY) { / ...

  10. 关于dc.add(Restrictions.like(&quot;XXX&quot;, &quot;%&quot;+XXX+&quot;%&quot;))查询不到结果,但数据库中存在

    找了好久,最后发现是连接池的jdbc.jdbcUrl=jdbc:mysql:///XXX没有写编码格式 把jdbc.jdbcUrl改为jdbc:mysql:///XXX?characterEncodi ...