• hdu3124Arbiter(最小圆距离-扫描线)


    链接

    详解http://blog.sina.com.cn/s/blog_6e7b12310100qnex.html

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 using namespace std;
     11 #define N 100000
     12 #define LL long long
     13 #define INF 0xfffffff
     14 const double eps = 1e-8;
     15 const double pi = acos(-1.0);
     16 const double inf = ~0u>>2;
     17 set<int>st;
     18 struct point
     19 {
     20     double x,y,r;
     21     point(double x = 0,double y = 0):x(x),y(y){}
     22     int id;
     23 }p[N],rank[N];
     24 struct line
     25 {
     26     double po;
     27     int id;
     28 }lef[N],rig[N];
     29 int rk[N],n,pp[N];
     30 double mid;
     31 typedef point pointt;
     32 point operator -(point a,point b)
     33 {
     34     return point(a.x-b.x,a.y-b.y);
     35 }
     36 int dcmp(double x)
     37 {
     38     if(fabs(x)<eps) return 0;
     39     return x<0?-1:1;
     40 }
     41 double dis(point a)
     42 {
     43     return sqrt(a.x*a.x+a.y*a.y*1.0);
     44 }
     45 int is_cross(int a,int b)
     46 {
     47     double dd = dis(rank[a]-rank[b]);
     48     if(dcmp(dd-rank[a].r-rank[b].r-mid-mid)>0) return 0;
     49     return 1;
     50 }
     51 int judge(int a)
     52 {
     53     set<int>::iterator it=st.insert(a).first;//插入a后所在位置
     54     if(it!=st.begin())
     55     {
     56         if(is_cross(a,*--it))
     57         return 1;
     58         it++;
     59     }
     60     if(++it!=st.end())
     61     {
     62         if(is_cross(a,*it)) return 1;
     63     }
     64     return 0;
     65 }
     66 int cal()
     67 {
     68     st.clear();
     69     int i = 1,j = 1;
     70     while(i<=n||j<=n)
     71     {
     72         if(j==n+1||(i!=n+1&&dcmp(lef[i].po-mid-(rig[j].po+mid))<=0))//如果当且i圆的最左端小于j圆的最右端 将i插进来
     73         {
     74             int ip = rk[lef[i].id];
     75             if(judge(ip))
     76             return 1;
     77             i++;
     78         }
     79         else
     80         {
     81             st.erase(rk[rig[j].id]);
     82             j++;
     83         }
     84     }
     85     return 0;
     86 }
     87 double solve()
     88 {
     89     double low = 0.0,high = dis(p[1]-p[2])-p[1].r-p[2].r;
     90     while(low+eps<high)//二分距离
     91     {
     92         mid = (high+low)/2;
     93         if(cal())
     94         high = mid;
     95         else low = mid;
     96     }
     97     return high+low;
     98 }
     99 bool cmp(line a,line b)
    100 {
    101     return a.po<b.po;
    102 }
    103 bool cmpp(point a,point b)
    104 {
    105     if(a.y==b.y) return a.x<b.x;
    106     return a.y<b.y;
    107 }
    108 int main()
    109 {
    110     int t,i;
    111     cin>>t;
    112     while(t--)
    113     {
    114         scanf("%d",&n);
    115         for(i = 1; i <=n ;i++)
    116         {
    117             scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);
    118             lef[i].po = p[i].x-p[i].r;//每个圆的最左端
    119             lef[i].id = i;
    120             rig[i].po = p[i].x+p[i].r;//每个圆的最右端
    121             rig[i].id = i;
    122             rank[i] = p[i];//按y坐标排序
    123             rank[i].id = i;
    124         }
    125         sort(lef+1,lef+n+1,cmp);
    126         sort(rig+1,rig+n+1,cmp);
    127         sort(rank+1,rank+n+1,cmpp);
    128         for(i = 1; i <= n; i++)
    129         {
    130             rk[rank[i].id] = i;//每个圆按y坐标排序后位于第几
    131         }
    132         double ans = solve();
    133         printf("%.6f
    ",ans);
    134     }
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    最大流模板
    大数相加
    . Number throry
    掷骰子 dp
    Java常用类库2
    简单注册功能(未连接数据库)
    Java常用类库
    人机猜拳
    租车系统
    Java一些概念
  • 原文地址:https://www.cnblogs.com/shangyu/p/3914804.html
Copyright © 2020-2023  润新知