王女Xiaoyun保存SDOI2012(+バイナリサーチ)

悪い習慣:

実際には、チーズ+質問の半分は、2点境界は下の境界と右の境界に接続され、下の境界と右の境界に左境界聯通のための合法的ではありません。

#include<queue>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
const int maxm=3100;
const double eps=1e-5;
int k,n,m,tot;
double xx[maxm],yy[maxm];
int q[maxm];
bool vis[maxm];
double ans,rr;
bool flag=0;
double dis(int x,int y)
{
 return sqrt((xx[x]-xx[y])*(xx[x]-xx[y])+(yy[x]-yy[y])*(yy[x]-yy[y]));  
}
void dfs(int x)
{
 vis[x]=1;
 if((n-xx[x]<rr)||(yy[x]-1.0<rr))
 {
  flag=1;
  return;
 }
 for(int i=1;i<=k;i++)
 {
  if(vis[i]) continue;
  if(dis(x,i)<2*rr)
  {
    dfs(i);
    if(flag)
    return;
  }
 }  
}
bool check(double x)
{
 tot=0;
 rr=x;
 flag=0;
 for(int i=1;i<=k;i++)
 {
   vis[i]=0;
   if((xx[i]-1.0<rr)||(m-yy[i]<rr))
   q[++tot]=i;
 }
 for(int i=1;i<=tot;i++)
 {
  if(!vis[q[i]])
  {
    dfs(q[i]);
    if(flag)
    return 0;
  }
 }
 return 1;
}
int main()
{
 scanf("%d%d%d",&k,&n,&m);
 for(int i=1;i<=k;i++)
 scanf("%lf%lf",xx+i,yy+i);
 double l=0,r=max(n,m);
 while(l+eps<=r)
 {
  double mid=(l+r)/2.0;
  if(check(mid))
  {
    ans=mid;
    l=mid+eps;
  }
  else r=mid-eps;
 }
 printf("%.2lf\n",ans);
 return 0;  
}

おすすめ

転載: www.cnblogs.com/lihan123/p/11803106.html