zoukankan      html  css  js  c++  java
  • 6489. 【GDOI2020模拟02.29】守卫疆域guard

    题目描述


    题解

    感觉枚举两个点之后二分半径不满足二分性,因此枚举了两个点之后对于剩下的点找圆心在这两个点的中垂线上的区间

    然后常数就炸了(


    二分答案,枚举一个在边界上的点,考虑把圆绕着该点转一圈

    那么对于其他的点就可以表示成一个区间,在区间内会被计算到

    排序判断即可,注意判断完全碰不到的情况

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define abs(x) ((x)>0?(x):-(x))
    #define sqr(x) ((x)*(x))
    #define inf 2133333333
    #define E 0.000000001
    #define ll long long
    #define file
    using namespace std;
    
    struct type{
    	double x,y;
    } a[501];
    struct Type{
    	double x;
    	int s;
    } b[2001];
    int n,m,i,j,k,l,tot;
    double L,R,Mid,ans,dis;
    
    bool cmp(Type a,Type b) {return abs(a.x-b.x)>E && a.x<b.x || abs(a.x-b.x)<=E && a.s>b.s;}
    
    void add(double t1,double t2)
    {
    	b[++tot]={t1,1};
    	b[++tot]={t2,-1};
    }
    
    bool pd(double R)
    {
    	int i,j,k,l,sum;
    	double dis,theta,theta2;
    	
    	fo(i,1,n)
    	{
    		sum=tot=0;
    		
    		fo(j,1,n)
    		{
    			dis=sqrt(sqr(a[i].x-a[j].x)+sqr(a[i].y-a[j].y));
    			
    			if (dis<=E)
    			++sum;
    			else
    			if (R*2>=dis)
    			{
    				theta=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
    				theta2=acos(dis/(R*2));
    				if (theta<0) theta+=M_PI*2;
    				
    				if (theta-theta2<0)
    				add(theta-theta2+M_PI*2,M_PI*2),add(0,theta+theta2);
    				else
    				if (theta+theta2>M_PI*2)
    				add(theta-theta2,M_PI*2),add(0,theta+theta2-M_PI*2);
    				else
    				add(theta-theta2,theta+theta2);
    			}
    		}
    		
    		if (!tot)
    		{
    			if (sum>=m)
    			return 1;
    			continue;
    		}
    		if (sum+tot/2<m) continue;
    		
    		stable_sort(b+1,b+tot+1,cmp);
    		
    		fo(j,1,tot)
    		{
    			sum+=b[j].s;
    			if (sum>=m) return 1;
    		}
    	}
    	
    	return 0;
    }
    
    int main()
    {
    	freopen("guard.in","r",stdin);
    	#ifdef file
    	freopen("guard.out","w",stdout);
    	#endif
    	
    	scanf("%d%d",&n,&m);
    	fo(i,1,n)
    	scanf("%lf%lf",&a[i].x,&a[i].y);
    	
    	if (m==1)
    	{
    		printf("0
    ");
    		return 0;
    	}
    	else
    	if (m==2)
    	{
    		ans=inf;
    		fo(i,1,n-1)
    		{
    			fo(j,i+1,n)
    			{
    				dis=sqrt(sqr(a[i].x-a[j].x)+sqr(a[i].y-a[j].y));
    				ans=min(ans,dis/2);
    			}
    		}
    		
    		printf("%.10lf
    ",ans);
    		return 0;
    	}
    	
    	L=0;
    	R=7072;
    	while (R-L>0.0001)
    	{
    		Mid=(L+R)/2;
    		
    		if (!pd(Mid))
    		L=Mid;
    		else
    		R=Mid;
    	}
    	
    	printf("%.10lf
    ",L);
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    初来乍到
    windows小技巧:远程桌面连接rdp文件
    CSS小试牛刀
    Windows phone 7之样式与模板
    Pulldowntorefresh a WP7 ListBox or ScrollViewer(向上向下的手势)
    Windows Phone 7 文件下载进度和速度显示
    WPF Binding
    wp7学习笔记(转)
    WP7 网络请求之WebClient
    Windows Phone Tilt effect on HubTile and other Controls
  • 原文地址:https://www.cnblogs.com/gmh77/p/12392849.html
Copyright © 2011-2022 走看看