zoukankan      html  css  js  c++  java
  • 【Comet OJ

    Description

    传送门

    • 在平面上给定 n 个点和一个 d,要求找到一条直线 l,使得到 l 的距离不超过 d 的点的个数最大。输出该最大点数。
      1≤n≤2000,0≤d≤10000

    Solution

    • 显然这条直线l往两边平移d的距离后的两条直线一定经过分别经过一个点。
    • 否则就可以通过调整使其满足。
    • 那么我们就可以枚举往左平移的那条线经过的点,现在要求的是经过一个点的所有直线它的右手方向2d的距离最多有多少个点。
    • 刚开始我想的是这条直线一定还被另一个点限制,这样再枚举一个点就可以确定一条直线了。但是这样子并不好就算向右2d中右多少个点。
    • 我们反过来考虑。
    • 对于一个点,它如果要在这条直线的范围内的话,这个直线的与水平线的夹角应该在哪个范围之内。
      在这里插入图片描述
    • 简单的推算后我们知道,对于与枚举的直线经过点O距离2d以外的点,在一个直角三角形的范围内可以被覆盖到。
    • 相反的方向也有一个三角形,同理,因为这条直线的夹角在(0,2PI)之间
    • 然后对于在2d以内的,它的贡献区间是过原点直线的一边。
    • 单个点的贡献区间都是不想交的。
    • 离散化之后求最大覆盖就好了。
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define maxn 2005
    #define db double
    #define E 1e-9
    using namespace std;
    
    const db PI=acos(-1);
    int n,d,i,j,k,x[maxn],y[maxn],ans,cnt,tot;
    db p,q; 
    struct line{
    	db k; int t,fr;
    } l[maxn*maxn];
    int cmp(line a,line b){
    	return abs(a.k-b.k)>E&&a.k<b.k || abs(a.k-b.k)<=E&&a.t>b.t;
    }
    
    db sqr(db x){return x*x;}
    db dis(int i,int j){return sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));}
    
    void insert(db k,int t){tot++,l[tot].k=k,l[tot].t=t,l[tot].fr=i;}
    void add(db x,db y){
    	if (x>=2*PI) x-=2*PI;
    	if (y>=2*PI) y-=2*PI;
    	if (x<=y) insert(x,1),insert(y,-1);
    	if (x>y) insert(x,1),insert(2*PI,-1),insert(0,1),insert(y,-1);
    }
    
    int main(){
    	scanf("%d%d",&n,&d);
    	for(i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
    	for(int s=1;s<=n;s++) {
    		tot=0;
    		for(i=1;i<=n;i++) if (i!=s){
    			if (x[i]==x[s]) p=((y[i]>y[s])?1:-1)*PI/2; else p=atan(1.0*(y[i]-y[s])/(x[i]-x[s]));
    			if (x[i]<x[s]) p+=PI;
    			if (p<0) p+=PI*2;
    			if (2.0*d>=dis(i,s)) 
    				add(p,p+PI); 
    			else {
    				q=asin(2.0*d/dis(i,s));
    				add(p,p+q);
    				add(p+PI-q,p+PI);
    			}
    		}
    		sort(l+1,l+1+tot,cmp);
    		cnt=0;
    		for(i=1;i<=tot;i++){
    			cnt+=l[i].t;
    			ans=max(ans,cnt);
    		}
    	}
    	printf("%d",ans+1);
    }
    
    
  • 相关阅读:
    不能说的话
    为什么书呆子不受欢迎
    Enum
    扩展方法
    若(p,q)=1,则(p^n,q^n)=1
    若a与m互质,则a不影响m的完全剩余组
    模m的剩余类里的一切数与m的最大公约数相等
    若p是与10互质的质数,则p-1个9能被p整除
    class.__subclasses__()
    权利要求书
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/13090936.html
Copyright © 2011-2022 走看看