zoukankan      html  css  js  c++  java
  • 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
    Submit: 1945  Solved: 853
    [Submit][Status][Discuss]

    Description

     

    题解

    显然矩形一边一定在凸包一边上

    旋转卡壳维护其他三条边经过的顶点

    更新答案

    这题1A欸嘿嘿

    代码

    //by 减维
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<bitset>
    #include<set>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<ctime>
    #include<algorithm>
    #define LL long long
    #define db double
    #define inf 1<<30
    #define maxn 50005
    #define eps 1e-8
    using namespace std;
    
    struct node{
        db x,y;
    }poi[maxn],sta[maxn],ans[15];
    
    int n,top;
    db mn=100000000.00;
    
    bool cmp(node x,node y){if(x.x==y.x)return x.y<y.y;return x.x<y.x;}
    bool cm2(node x,node y){if(x.x==y.x)return x.y>y.y;return x.x>y.x;}
    node operator - (node x,node y){return (node){x.x-y.x,x.y-y.y};}
    node operator + (node x,node y){return (node){x.x+y.x,x.y+y.y};}
    node operator * (node x,db y){return (node){x.x*y,x.y*y};}
    node operator * (db x,node y){return (node){x*y.x,x*y.y};}
    db operator * (node x,node y){return x.x*y.y-x.y*y.x;}
    db operator / (node x,node y){return x.x*y.x+x.y*y.y;}
    bool operator == (node x,node y){return x.x==y.x&&x.y==y.y;}
    bool operator > (node x,node y){if(x.y==y.y)return x.x>x.y;return x.y>y.y;}
    db dis(node x,node y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}
    
    void solve()
    {
        db ds,h,ll,rr;
        int t=0,l=0,r=0;
        sta[0]=sta[top];
        for(int i=0;i<top;++i)
        {
            ds=dis(sta[i],sta[i+1]);
            while((sta[i+1]-sta[i])*(sta[t+1]-sta[i])-(sta[i+1]-sta[i])*(sta[t]-sta[i])>-eps)t=(t+1)%top;
            while((sta[i+1]-sta[i])/(sta[r+1]-sta[i])-(sta[i+1]-sta[i])/(sta[r]-sta[i])>-eps)r=(r+1)%top;
            if(i==0)l=r;
            while((sta[i+1]-sta[i])/(sta[l]-sta[i])-(sta[i+1]-sta[i])/(sta[l+1]-sta[i])>-eps)l=(l+1)%top;
            ll=(sta[i+1]-sta[i])/(sta[l]-sta[i])/ds;
            rr=(sta[i+1]-sta[i])/(sta[r]-sta[i])/ds;
            h=(sta[i+1]-sta[i])*(sta[t]-sta[i])/ds;
            if(mn>(rr-ll)*h){
                mn=(rr-ll)*h;
                ans[0]=sta[i]+(sta[i+1]-sta[i])*(rr/ds);
                ans[1]=ans[0]+(sta[r]-ans[0])*(h/dis(sta[r],ans[0]));
                ans[2]=ans[1]+(sta[t]-ans[1])*((rr-ll)/dis(sta[t],ans[1]));
                ans[3]=ans[2]+(ans[0]-ans[1]);
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%lf%lf",&poi[i].x,&poi[i].y);
        sort(poi+1,poi+n+1,cmp);
        sta[++top]=poi[1];sta[++top]=poi[2];
        for(int i=3;i<=n;++i){
            while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>=2)top--;
            sta[++top]=poi[i];
        }
        sort(poi+1,poi+n+1,cm2);
        int sa=top;
        if(sta[top]==poi[1])sta[++top]=poi[2],sa--;
        else sta[++top]=poi[1],sta[++top]=poi[2];
        for(int i=3;i<=n;++i){
            while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>sa)top--;
            sta[++top]=poi[i];
        }
        top--;
        solve();
        printf("%.5lf
    ",mn);
        int fir=0;
        for(int i=1;i<=3;++i)if(ans[fir]>ans[i])fir=i;
        for(int i=0;i<=3;++i)printf("%.5lf %.5lf
    ",ans[(fir+i)%4],ans[(fir+i)%4]);
        return 0;
    }
  • 相关阅读:
    octotree神器 For Github and GitLab 火狐插件
    实用篇如何使用github(本地、远程)满足基本需求
    PPA(Personal Package Archives)简介、兴起、使用
    Sourse Insight使用过程中的常使用功能简介
    Sourse Insight使用教程及常见的问题解决办法
    github 遇到Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts问题解决
    二叉查找树的C语言实现(一)
    初识内核链表
    container_of 和 offsetof 宏详解
    用双向链表实现一个栈
  • 原文地址:https://www.cnblogs.com/rir1715/p/8136747.html
Copyright © 2011-2022 走看看