• bzoj1185 [HNOI2007]最小矩形覆盖


    Description

    正解:凸包+旋转卡壳。

    这道题思路也是比较显然的。首先我们可以想到,最小矩形的一条边肯定是凸包上的一条边。然后我们用旋转卡壳枚举每一条边,并算出距离这条边最远的点,左边最远的点和右边最远的点,然后用一下叉积点积什么的算出面积和点就行了。

    比较坑的是,答案可能会爆成$-0.00000$,然后必须加一个特判才行。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <queue>
     10 #include <stack>
     11 #include <map>
     12 #include <set>
     13 #define inf (1<<30)
     14 #define N (100010)
     15 #define eps (1e-8)
     16 #define il inline
     17 #define RG register
     18 #define ll long long
     19 #define ld long double
     20 
     21 using namespace std;
     22 
     23 int n,top;
     24 ld ans;
     25 
     26 struct point{
     27     
     28     ld x,y;
     29     
     30     il bool operator == (const point &a) const{
     31     return x==a.x && y==a.y;
     32     }
     33     
     34     il bool operator < (const point &a) const{
     35     if (x==a.x) return y<a.y; return x<a.x;
     36     }
     37 
     38     il point operator + (const point &a) const{
     39     return (point){x+a.x,y+a.y};
     40     }
     41 
     42     il point operator - (const point &a) const{
     43     return (point){x-a.x,y-a.y};
     44     }
     45 
     46     il point operator * (const ld &v) const{
     47     return (point){x*v,y*v};
     48     }
     49 
     50     il point operator / (const ld &v) const{
     51     return (point){x/v,y/v};
     52     }
     53     
     54 }p[N],st[N],po[5],Ans;
     55 
     56 il ld dot(RG point a,RG point b){ return a.x*b.x+a.y*b.y; }
     57 
     58 il ld cross(RG point a,RG point b){ return a.x*b.y-a.y*b.x; }
     59 
     60 il ld dis(RG point a,RG point b){
     61     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     62 }
     63 
     64 il point get(RG point p,RG point a,RG point b){
     65     RG point v=b-a; return a+v*dot(v,p-a)/dot(v,v);
     66 }
     67 
     68 il int cmp1(const point &a,const point &b){
     69     if (a.y==b.y) return a.x<b.x; return a.y<b.y;
     70 }
     71 
     72 il int cmp2(const point &a,const point &b){
     73     return atan2(a.y-Ans.y,a.x-Ans.x)<atan2(b.y-Ans.y,b.x-Ans.x);
     74 }
     75 
     76 il int gi(){
     77     RG int x=0,q=1; RG char ch=getchar();
     78     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     79     if (ch=='-') q=-1,ch=getchar();
     80     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
     81     return q*x;
     82 }
     83 
     84 int main(){
     85 #ifndef ONLINE_JUDGE
     86     freopen("square.in","r",stdin);
     87     freopen("square.out","w",stdout);
     88 #endif
     89     n=gi(); for (RG int i=1;i<=n;++i) scanf("%Lf%Lf",&p[i].x,&p[i].y);
     90     sort(p+1,p+n+1),st[++top]=p[1];
     91     for (RG int i=2;i<=n;++i){
     92     while (top>=2 && cross(st[top]-st[top-1],p[i]-st[top-1])<eps) --top;
     93     st[++top]=p[i];
     94     }
     95     RG int la=top,l,r=2,pos=2; ans=1e100;
     96     for (RG int i=n-1;i;--i){
     97     while (top>la && cross(st[top]-st[top-1],p[i]-st[top-1])<eps) --top;
     98     st[++top]=p[i];
     99     }
    100     for (RG int i=1;i<top;++i){
    101     RG ld D=dis(st[i],st[i+1]);
    102     while (cross(st[i+1]-st[i],st[pos+1]-st[i])>=cross(st[i+1]-st[i],st[pos]-st[i])) pos=pos%(top-1)+1;
    103     while (dot(st[i+1]-st[i],st[r+1]-st[i])>=dot(st[i+1]-st[i],st[r]-st[i])) r=r%(top-1)+1; if (i==1) l=r;
    104     while (dot(st[i+1]-st[i],st[l+1]-st[i])<=dot(st[i+1]-st[i],st[l]-st[i])) l=l%(top-1)+1;
    105     RG ld L=dot(st[i+1]-st[i],st[l]-st[i])/D,R=dot(st[i+1]-st[i],st[r]-st[i])/D;
    106     RG ld H=cross(st[i+1]-st[i],st[pos]-st[i])/D,res=H*(R-L); if (res<0) res=-res;
    107     if (ans>res){
    108         ans=res;
    109         po[1]=st[i]+(st[i+1]-st[i])*(R/D);
    110         po[2]=st[i]+(st[i+1]-st[i])*(L/D);
    111         po[3]=po[1]+(st[r]-po[1])*(H/dis(po[1],st[r]));
    112         po[4]=po[2]+po[3]-po[1];
    113         if (po[1].x<eps && po[1].x>-eps) po[1].x=fabs(po[1].x);
    114         if (po[1].y<eps && po[1].y>-eps) po[1].y=fabs(po[1].y);
    115         if (po[2].x<eps && po[2].x>-eps) po[2].x=fabs(po[2].x);
    116         if (po[2].y<eps && po[2].y>-eps) po[2].y=fabs(po[2].y);
    117         if (po[3].x<eps && po[3].x>-eps) po[3].x=fabs(po[3].x);
    118         if (po[3].y<eps && po[3].y>-eps) po[3].y=fabs(po[3].y);
    119         if (po[4].x<eps && po[4].x>-eps) po[4].x=fabs(po[4].x);
    120         if (po[4].y<eps && po[4].y>-eps) po[4].y=fabs(po[4].y);
    121     }
    122     }
    123     printf("%0.5Lf
    ",ans),sort(po+1,po+5,cmp1),Ans=po[1]; sort(po+1,po+5,cmp2);
    124     for (RG int i=1;i<=4;++i) printf("%0.5Lf %0.5Lf
    ",po[i].x,po[i].y);
    125     return 0;
    126 }
  • 相关阅读:
    方法
    逻辑运算符/三元运算符/Scanner
    多线程线程状态和案例演示
    实现多线程的两种方式
    初识多线程
    IO流一些问题的总结
    IO流—其他流
    厦门Android开发三年,工资不到1w,敢问路在何方?
    二本渣渣考研失败,幸得知乎内推,成功拿下Android开发offer!
    2020Android面试心得,已拿到offer
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7266773.html
Copyright © 2020-2023  润新知