zoukankan      html  css  js  c++  java
  • GCJ2009B&JZOJ 4033 Min Perimeter

    SOL:

     我们参考最近点对的做法,分治加当前最优解剪枝。

    #pragma GCC optimize("-Ofast")
    #include<bits/stdc++.h>
    using namespace std;
    #define max(a,b) ((a)<(b)?(b):(a))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fo(i,j,k) for (int i=(j);i<=(k);i++)
    #define fd(i,j,k) for (int i=(j);i>=(k);i--)
    #define fe(i,j) for (int j=head[i];j!=-1;j=mp[j].next)
    #define fuck printf("666"
    );
    #define scan freopen("in.txt","r",stdin)
    #define print freopen("out.txt","w",stdout)
    const double inf=1e+20;
    const int bil=1e+9;
    struct P
    {
      int x,y;
    }px[100001];
    int n;
    vector<P> py;
    inline char nc()
    {
      static char buf[100000],*p1=buf,*p2=buf;
      if (p1==p2)
      {
        p2=(p1=buf)+fread(buf,1,100000,stdin);
        if (p1==p2) return EOF;
      }
      return *p1++;
    }
    inline void read(int &x)
    {
      char c=nc();int b=1;
      for (;c<'0'||c>'9';c=nc()) if (c=='-') b=-1;
      for (x=0;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
      x=x*b;
    }
    inline void read(long long &x)
    {
      char c=nc();int b=1;
      for (;c<'0'||c>'9';c=nc()) if (c=='-') b=-1;
      for (x=0;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
      x=x*b;
    }
    inline bool cmpx(const P& a,const P& b)
    {
      if (a.x!=b.x) return a.x<b.x;
      return a.y<b.y;
    }
    inline bool cmpy(const P& a,const P& b)
    {
      if (a.y!=b.y) return a.y<b.y;
      return a.x<b.x;
    }
    inline double dis(P a,P b)
    {
      return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    inline double calc(P a,P b,P c)
    {
      return dis(a,b)+dis(a,c)+dis(b,c);
    }
    double ou,res=inf;
    void solve(int l,int r,const vector<P> &Py)
    {
    //  if (r-l+1<3) return inf;
      if (r-l<10) {
          for (int i=l;i<r;i++)
           for (int j=i+1;j<r;j++)
            for (int k=j+1;k<=r;k++)
             ou=calc(px[i],px[j],px[k]),
             res=min(res,ou); return;
      }
      int mid=(l+r)/2;
      int tmp=(px[mid].x+px[mid+1].x)/2;
    //  double res=inf;
      vector<P> py1;py1.reserve(mid-l+1);
      vector<P> py2;py2.reserve(r-mid);
      fo(i,0,(int)Py.size()-1)
      {
        if (Py[i].x<tmp) py1.push_back(Py[i]);
        else py2.push_back(Py[i]);
      }
      solve(l,mid,py1),solve(mid+1,r,py2);
      int up,head=0;
      if (res>inf/2) up=bil*2;
      else up=(int)(res/2);
      static vector<P> temp;
      temp.clear();
      temp.reserve(r-l+1);
      fo(i,0,r-l)
      {
        P p=Py[i];
        if (abs(p.x-tmp)>up) continue;
        while (head<(int)temp.size()&&p.y-temp[head].y>up) head++;
        fo (i,head,(int)temp.size()-1)
        {
          fo(j,i+1,(int)temp.size()-1)
          res=min(res,calc(p,temp[i],temp[j]));
        }
        temp.push_back(p);
      }
      return;
    }
    int main(int argc, char *argv[])
    {
      read(n);
      fo(i,1,n)
      read(px[i].x),read(px[i].y),px[i].x=px[i].x*2-bil/2,px[i].y=px[i].y*2-bil/2,py.push_back(px[i]);
      sort(px+1,px+n+1,cmpx);
      sort(py.begin(),py.end(),cmpy);
      solve(1,n,py);
      printf("%0.13lf",res/2);
      return 0;
    }
  • 相关阅读:
    hihocoder 1142 三分·三分求极值(三分)
    poj 3304 Segments(计算直线与线段之间的关系)
    poj 1269 Intersecting Lines(判断两直线关系,并求交点坐标)
    poj 2398 Toy Storage(计算几何 点线关系)
    poj 2318 TOYS(计算几何 点与线段的关系)
    计算几何基础(模板)
    Jmeter-基本组成
    java-面向对象
    性能测试基础
    java-多线程
  • 原文地址:https://www.cnblogs.com/rrsb/p/9299149.html
Copyright © 2011-2022 走看看