传送门

不难看出最后的矩形一定有一条边与凸包某条边重合。

因此先求出凸包,然后旋转卡壳求出当前最小矩形面积更新答案。

代码:

  1. #include<bits/stdc++.h>
  2. #define N 50005
  3. #define eps 1e-9
  4. using namespace std;
  5. struct pot{
  6. long double x,y;
  7. inline pot operator+(const pot&a){return (pot){x+a.x,y+a.y};}
  8. inline pot operator-(const pot&a){return (pot){x-a.x,y-a.y};}
  9. inline long double operator^(const pot&a){return x*a.y-y*a.x;}
  10. inline long double operator*(const pot&a){return x*a.x+y*a.y;}
  11. inline pot operator*(const long double&a){return (pot){x*a,y*a};}
  12. inline long double dist(){return sqrt(x*x+y*y);}
  13. friend inline bool operator<(pot a,pot b){return fabs(a.y-b.y)<eps?a.x<b.x:a.y<b.y;}
  14. inline pot rev(){return (pot){-y,x};}
  15. }p[N],ans[5],now[5];
  16. int n,q[N],top=0;
  17. long double sum=1e18;
  18. inline bool cmp(pot x,pot y){
  19. long double tmp=(x-p[1])^(y-p[1]);
  20. if(fabs(tmp)>eps)return tmp>0;
  21. return (x-p[1]).dist()<(y-p[1]).dist();
  22. }
  23. inline void graham(){
  24. int tmp=1;
  25. for(int i=2;i<=n;++i)if(p[i]<p[tmp])tmp=i;
  26. if(tmp^1)swap(p[tmp],p[1]);
  27. sort(p+2,p+n+1,cmp),q[++top]=1;
  28. for(int i=2;i<=n;++i){
  29. while(top>=2&&((p[q[top]]-p[q[top-1]])^(p[i]-p[q[top-1]]))<eps)--top;
  30. q[++top]=i;
  31. }
  32. q[0]=q[top];
  33. }
  34. int main(){
  35. scanf("%d",&n);
  36. for(int i=1;i<=n;++i)scanf("%Lf%Lf",&p[i].x,&p[i].y);
  37. graham();
  38. for(int i=0,l=1,r=1,h=1;i<top;++i){
  39. long double Dis=(p[q[i+1]]-p[q[i]]).dist();
  40. while(((p[q[i+1]]-p[q[i]])^(p[q[h+1]]-p[q[i]]))-((p[q[i+1]]-p[q[i]])^(p[q[h]]-p[q[i]]))>-eps)h=(h+1)%top;
  41. while((p[q[i+1]]-p[q[i]])*(p[q[r+1]]-p[q[i]])-(p[q[i+1]]-p[q[i]])*(p[q[r]]-p[q[i]])>-eps)r=(r+1)%top;
  42. if(!i)l=r;
  43. while((p[q[i+1]]-p[q[i]])*(p[q[l+1]]-p[q[i]])-(p[q[i+1]]-p[q[i]])*(p[q[l]]-p[q[i]])<eps)l=(l+1)%top;
  44. long double L=(p[q[i+1]]-p[q[i]])*(p[q[l]]-p[q[i]])/Dis,R=(p[q[i+1]]-p[q[i]])*(p[q[r]]-p[q[i]])/Dis;
  45. long double H=fabs(((p[q[i+1]]-p[q[i]])^(p[q[h]]-p[q[i]]))/Dis),tmp=(R-L)*H;
  46. if(tmp<sum){
  47. sum=tmp;
  48. ans[1]=p[q[i]]+(p[q[i+1]]-p[q[i]])*(R/Dis);
  49. ans[2]=ans[1]+(p[q[r]]-ans[1])*(H/(ans[1]-p[q[r]]).dist());
  50. ans[3]=ans[2]-(ans[1]-p[q[i]])*((R-L)/(p[q[i]]-ans[1]).dist());
  51. ans[4]=ans[3]+ans[1]-ans[2];
  52. }
  53. }
  54. printf("%.5Lf\n",sum);
  55. int pos=1;
  56. for(int i=1;i<=4;++i){
  57. if(fabs(ans[i].x)<eps)ans[i].x=0;
  58. if(fabs(ans[i].y)<eps)ans[i].y=0;
  59. }
  60. for(int i=2;i<=4;++i)if(ans[i]<ans[pos])pos=i;
  61. for(int i=1;i<=4;++i){
  62. printf("%.5Lf %.5Lf\n",ans[pos].x,ans[pos].y);
  63. ++pos;
  64. if(pos==5)pos=1;
  65. }
  66. for(int i=1;i<=10;++i)puts("");
  67. return 0;
  68. }

2018.10.18 bzoj1185: [HNOI2007]最小矩形覆盖(旋转卡壳)的更多相关文章

  1. bzoj1185 [HNOI2007]最小矩形覆盖 旋转卡壳求凸包

    [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 2081  Solved: 920 ...

  2. 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)

    题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...

  3. BZOJ 1185: [HNOI2007]最小矩形覆盖 [旋转卡壳]

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

  4. 【bzoj1185】[HNOI2007]最小矩形覆盖 (旋转卡壳)

    给你一些点,让你用最小的矩形覆盖这些点 首先有一个结论,矩形的一条边一定在凸包上!!! 枚举凸包上的边 用旋转卡壳在凸包上找矩形另外三点... 注意精度问题 #include<cstdio> ...

  5. bzoj 1185 [HNOI2007]最小矩形覆盖——旋转卡壳

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1185 矩形一定贴着凸包的一条边.不过只是感觉这样. 枚举一条边,对面的点就是正常的旋转卡壳. ...

  6. BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子

    来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...

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

    BZOJ1185[HNOI2007] 最小矩形覆盖 题面 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形,输出所求矩形的面积和四个顶点的坐标 分析 首先可以先求凸包,因为覆盖了凸包上的顶点,凸 ...

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

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

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

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

随机推荐

  1. JAVA servlet 上传文件(commons-fileupload, commons-io)

    <1>获取二进制文件流并输出 InputStream inputStream = request.getInputStream(); BufferedReader reader = new ...

  2. PHP 使用协同程序实现合作多任务

    多任务协作 如果阅读了上面的logger()例子,那么你认为“为了双向通信我为什么要使用协程呢? 为什么我不能只用常见的类呢?”,你这么问完全正确.上面的例子演示了基本用法,然而上下文中没有真正的展示 ...

  3. eclipse web run on server 404

    eclipse真是个坑爹玩意儿,前期在idea开发的web,移到eclipse遇到各种问题 刚开始好好的,突然404,不明所以,搞了好几天 参考eclipse修改web项目部署路径 解决了问题 后来发 ...

  4. Tomcat 异常关闭排查

    N次请求 tomcat conf/server.xml https://blog.csdn.net/qq_30121245/article/details/52861935 pattern分析 %a ...

  5. AS3 歌词同步

    这里实例素材: 我们不一样.lrc 我们不一样.mp3 歌词同步其实就是靠lrc文本文件,打开它,可以看到时间点和对应的歌词. 打开lrc内容如下: [ti:我们不一样][ar:大壮][al:][by ...

  6. as3 判断鼠标移动方向

    import flash.events.MouseEvent; var odx:Number=mouseX; var ody:Number=mouseY; stage.addEventListener ...

  7. Ubuntu技巧之清理系统中无用的软件包

    如果你频繁的在你的系统中安装/卸载,那么不时的清理一下你的系统是十分必要的. 在Ubuntu终端中执行如下命令: sudo apt-get autoremove 屏幕输出是这个样子的: Reading ...

  8. Haskell语言学习笔记(48)Data.Tuple

    Data.Tuple fst :: (a,b) -> a fst (x,_) = x snd :: (a,b) -> b snd (_,y) = y curry :: ((a, b) -& ...

  9. Hadoop slaves 没有nodeManager

    1../start-yarn.sh 后从服务器没有nodemanager 进程,并且这里没有报错 在从服务器上的日志上见: 从服务器查看日志: 查看2.8.4官方文档: https://hadoop. ...

  10. Java8 Stream语法详解 2

    1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...