切比雪夫距離


[TJOI2013]松鼠聚會

兩個點 \((x_1,y_1),(x_2,y_2)\) 的切比雪夫距離為:\(\max(|x_1-x_2|,|y_1-y_2|)\)

這個東西非常不好處理,因為帶最值。

學習了轉換切比雪夫距離和曼哈頓距離的方法,而曼哈頓距離和是很好求的。

轉換公式為 \((x,y)\to (x+y,x-y)\),即可將曼哈頓距離轉換為切比雪夫距離。

\[|x_1-x_2|+|y_1-y_2|\ \ \& \ \ \max(|x_1+y_1-x_2-y_2|,|x_1-y_1-x_2+y_2|) \]

右邊那個可以化成:

\[\max(|(x_1-x_2)+(y_1-y_2)|,|(x_1-x_2)-(y_1-y_2)|) \]

會發現這個東西和左邊等價。

於是,證明成立。

那么返回去倒退即可得到:

切比雪夫轉換為曼哈頓:\((x,y)\to (\frac{x+y}{2},\frac{x-y}{2})\)

於是此題便可以得以解決。

#include <stdio.h>
#include <algorithm>
#define LL long long
using namespace std;
const int N=1e5+3;
inline LL min(LL x,LL y){return x<y?x:y;}
inline LL rin()
{
    LL s=0;
    bool bj=false;
    char c=getchar();
    for(;(c>'9'||c<'0')&&c!='-';c=getchar());
    if(c=='-')bj=true,c=getchar();
    for(;c>='0'&&c<='9';c=getchar())s=(s<<1)+(s<<3)+(c^'0');
    if(bj)s=-s;
    return s;
}

LL s_x;
LL s_y;
struct gyq
{
    LL x,y;
    LL sum;
    inline void init()
    {
        int x_=rin(),y_=rin();
        x=x_+y_;y=x_-y_;
        s_x+=x;s_y+=y;
        return;
    }
}a[N];
inline bool myru_x(gyq x,gyq y){return x.x<y.x;}
inline bool myru_y(gyq x,gyq y){return x.y<y.y;}
int main()
{
    int i,j;
    int n=rin();
    for(i=1;i<=n;i++)a[i].init();
    LL sum;
    sort(a+1,a+n+1,myru_x);
    for(i=1,sum=0;i<=n;i++)sum+=a[i].x,a[i].sum+=a[i].x*i-sum+(s_x-sum)-a[i].x*(n-i);
    sort(a+1,a+n+1,myru_y);
    for(i=1,sum=0;i<=n;i++)sum+=a[i].y,a[i].sum+=a[i].y*i-sum+(s_y-sum)-a[i].y*(n-i);
    LL ans=0x3f3f3f3f3f3f3f3f;
    for(i=1;i<=n;i++)ans=min(ans,a[i].sum);
    printf("%lld\n",ans>>1);
    return 0;
}

[POI2006]MAG-Warehouse

這題 \(x\)\(y\) 要分開做。

由於求得的新坐標雖然是整點,但轉變回去並不一定是,於是就可以擾動一下,看一下附近的一些點,找到一個轉回去是整點的最小值即可。

但是 WA 了,\(90\) 分。

算了一下,這個鬼東西剛好會炸 long long。

於是學會了 int128 的使用方法(

#include <stdio.h>
#include <algorithm>
#define LL long long
using namespace std;
const int N=1e5+3;
// inline LL abs(LL x){return (x<0)?(-x):(x);}
inline LL min(LL x,LL y){return x<y?x:y;}
inline __int128 min(__int128 x,__int128 y){return x<y?x:y;}
inline LL rin()
{
    LL s=0;
    bool bj=false;
    char c=getchar();
    for(;(c>'9'||c<'0')&&c!='-';c=getchar());
    if(c=='-')bj=true,c=getchar();
    for(;c>='0'&&c<='9';c=getchar())s=(s<<1)+(s<<3)+(c^'0');
    if(bj)s=-s;
    return s;
}

int n;
__int128 s_x;
__int128 s_y;
__int128 cutt;
struct gyq
{
    LL x,y;
    LL t;
    inline void init()
    {
        LL x_=rin(),y_=rin();
        x=x_+y_;y=x_-y_;
        t=rin();
        s_x+=x*t;
        s_y+=y*t;
        cutt+=t;
        return;
    }
}a[N];
inline bool myru_x(gyq x,gyq y){return x.x<y.x;}
inline bool myru_y(gyq x,gyq y){return x.y<y.y;}

inline __int128 cheak(LL x,LL y)
{
    __int128 sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=abs(a[i].t*(a[i].x-x));
        sum+=abs(a[i].t*(a[i].y-y));
    }
    return sum;
}
inline void work(LL x,LL y)
{
    if((x&1)==(y&1)){printf("%lld %lld\n",(x+y)>>1,(x-y)>>1);return;}
    __int128 s_1,s_2,s_3,s_4;
    s_1=cheak(x-1,y);
    s_2=cheak(x+1,y);
    s_3=cheak(x,y-1);
    s_4=cheak(x,y+1);
    __int128 ans=min(min(s_1,s_2),min(s_3,s_4));
    if(ans==s_1){printf("%lld %lld\n",(x-1+y>>1),(x-1-y>>1));return;}
    if(ans==s_2){printf("%lld %lld\n",(x+1+y>>1),(x+1-y>>1));return;}
    if(ans==s_3){printf("%lld %lld\n",(x+y-1>>1),(x-y+1>>1));return;}
    if(ans==s_4){printf("%lld %lld\n",(x+y+1>>1),(x-y-1>>1));return;}
    return;
}
int main()
{
    int i,j;
    n=rin();
    for(i=1;i<=n;i++)a[i].init();
    __int128 sum=0;
    __int128 cts=0;
    __int128 min_x,min_y;
    LL x=-1,y=-1;
    min_x=min_y=0x3f3f3f3f3f3f3f3f;
    min_x=min_y=min_x*min_x;
    sort(a+1,a+n+1,myru_x);
    for(i=1,sum=cts=0;i<=n;i++)
    {
        sum+=a[i].x*a[i].t;
        cts+=a[i].t;
        if(min_x>cts*a[i].x-sum+(s_x-sum)-(cutt-cts)*a[i].x)min_x=cts*a[i].x-sum+(s_x-sum)-(cutt-cts)*a[i].x,x=a[i].x;
    }
    sort(a+1,a+n+1,myru_y);
    for(i=1,sum=cts=0;i<=n;i++)
    {
        sum+=a[i].y*a[i].t;
        cts+=a[i].t;
        if(min_y>cts*a[i].y-sum+(s_y-sum)-(cutt-cts)*a[i].y)min_y=cts*a[i].y-sum+(s_y-sum)-(cutt-cts)*a[i].y,y=a[i].y;
    }
    work(x,y);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM