• 曼哈顿距离与切比雪夫距离的亲密♂关系。


    先来看一下曼哈顿距离和切比雪夫距离的定义。(以下我可能用(D_m,D_q)来表示两者)

    曼哈顿距离:(|x_1-x_2|+|y_1-y_2|)

    切比雪夫距离:(max(|x_1-x_2|,|y_1-y_2|))

    至于为什么说他俩关系♂,就是因为他们可以相互转化!

    转换关系如下:当坐标为((x,y))

    (D_m=)坐标为((x+y,x-y))时的(D_q)

    (D_q=)坐标为((dfrac{x+y}{2},dfrac{x-y}{2}))时的(D_q)

    经过向(Itst)神仙询问,将其区分开来:

    (D_m)常用于求和,而(D_q)常用于(max,min)

    而其中的绝对值,可以用排序去掉。

    (LuoguP2906Cow Neighborhoods)

    做法:现将曼哈顿距离转化为切比雪夫,排序,枚举每个点,删掉(x)的差已经大于(C)的点。

    再用(set)维护新(y_i)(及点的编号),找到第一个满足条件的点后就加群,在判断前一个是否满足,加群。

    群的关系用并查集维护就好了。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    inline int read()
    {
        int f=1,w=0;char x=0;
        while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
        while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
        return w*f;
    }
    const int N=100010;
    int n,fa[N],C,l=1,cnt[N],ansx,ans;
    pair<int,int> p[N];
    set<pair<int,int> > s;
    inline int Find(int x) {return fa[x]==x?x:fa[x]=Find(fa[x]);}
    main(){
    #ifndef ONLINE_JUDGE
        freopen("A.in","r",stdin);
    #endif
    	n=read(); C=read();
    	for(int i=1,x,y;i<=n;i++)
    		x=read(),y=read(),p[i]=make_pair(x+y,x-y),fa[i]=i;
    	sort(p+1,p+n+1);s.insert(make_pair(p[1].second,1));
    	s.insert(make_pair(-1LL<<60,0)),s.insert(make_pair(1LL<<60,0));
    	for(int i=2;i<=n;i++)
    	{
    		while(p[i].first-p[l].first>C) s.erase(make_pair(p[l].second,l)),l++;
    		set<pair<int,int> >::iterator it=s.lower_bound(make_pair(p[i].second,0));
    		if(it->first-p[i].second<=C) fa[Find(i)]=Find(it->second);it--;
    		if(p[i].second-it->first<=C) fa[Find(i)]=Find(it->second);
    		s.insert(make_pair(p[i].second,i));
    	}
    	for(int i=1;i<=n;i++) {cnt[Find(i)]++;if(Find(i)==i) ans++;}
    	for(int i=1;i<=n;i++) ansx=max(ansx,cnt[i]);
    	printf("%lld %lld",ans,ansx);
    }
    
    

    (Luogu[TJOI2013])松鼠聚会

    做法:将切比雪夫转曼哈顿,推公式,枚举聚会地点即可(当然还要排序

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    inline int read()
    {
        int f=1,w=0;char x=0;
        while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
        while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
        return w*f;
    }
    const int N=100010;
    int n,x[N],y[N],ans=1LL<<62,Sx[N],Sy[N],px[N],py[N];
    main(){
    #ifndef ONLINE_JUDGE
        //freopen("A.in","r",stdin);//Ans=20
        freopen("B.in","r",stdin);//Ans=15
    #endif
    	n=read();
    	for(int i=1,X,Y;i<=n;i++) X=read(),Y=read(),x[i]=px[i]=X+Y,y[i]=py[i]=X-Y;
    	sort(x+1,x+n+1);sort(y+1,y+n+1);
    	for(int i=1;i<=n;i++) Sx[i]=x[i]+Sx[i-1],Sy[i]=y[i]+Sy[i-1];
    	for(int i=1;i<=n;i++)
    	{
    		int sum=0,j=lower_bound(x+1,x+n+1,px[i])-x;
    		sum+=j*px[i]-Sx[j]+Sx[n]-Sx[j]-(n-j)*px[i];
    		j=lower_bound(y+1,y+n+1,py[i])-y;
    		sum+=j*py[i]-Sy[j]+Sy[n]-Sy[j]-(n-j)*py[i];ans=min(ans,sum);
    	}
    	printf("%lld",ans/2);
    }
    
    
  • 相关阅读:
    linux系统调用是通过软中断实现的吗
    Linux系统调用怎么和内核或底层驱动交互的
    strace命令
    linux 用户态和内核态以及进程上下文、中断上下文 内核空间用户空间理解
    C语言string.h常用函数总结
    shall的过去式和should怎么区分
    P(Y|X) 和 P(X,Y)
    Sourceinsight最佳配色方案及颜色字体调整方法
    float 为什么可以表示很大的整数
    协方差矩阵
  • 原文地址:https://www.cnblogs.com/wo-shi-zhen-de-cai/p/11184197.html
Copyright © 2020-2023  润新知