Meeting point-1 HDU - 4311 + Meeting point-2 HDU - 4312

http://acm.hdu.edu.cn/showproblem.php?pid=4311

http://acm.hdu.edu.cn/showproblem.php?pid=4312

4311求最小空间曼哈顿距离之和 4312求最小空间切比雪夫距离之和

空间三种距离总结http://www.cnblogs.com/adelalove/p/8612540.html

 

曼哈顿距离

在曼哈顿距离中x与y互不想干 分别排序后求一个前缀后缀即可

如果答案不要求在某一个点上的话 直接对每个维度排序取中位数

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=0x3f3f3f3f3f3f3f3f;

struct node
{
    ll x,y;
    int id;
};

node point[100010];
ll pre[100010],post[100010];
int n;

bool cmpI(node n1,node n2)
{
    return n1.x<n2.x;
}

bool cmpII(node n1,node n2)
{
    return n1.y<n2.y;
}

ll getmin(ll a,ll b)
{
    if(a<b) return a;
    else return b;
}

int main()
{
    ll i,sum,ans;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            point[i].id=i;
            scanf("%lld%lld",&point[i].x,&point[i].y);
        }
        memset(pre,0,sizeof(pre));
        memset(post,0,sizeof(post));

        sort(point+1,point+n+1,cmpI);
        sum=0;
        for(i=2;i<=n;i++)
        {
            sum+=(i-1)*(point[i].x-point[i-1].x);
            pre[point[i].id]+=sum;
        }
        sum=0;
        for(i=n-1;i>=1;i--)
        {
            sum+=(n-i)*(point[i+1].x-point[i].x);
            post[point[i].id]+=sum;
        }

        sort(point+1,point+n+1,cmpII);
        sum=0;
        for(i=2;i<=n;i++)
        {
            sum+=(i-1)*(point[i].y-point[i-1].y);
            pre[point[i].id]+=sum;
        }
        sum=0;
        for(i=n-1;i>=1;i--)
        {
            sum+=(n-i)*(point[i+1].y-point[i].y);
            post[point[i].id]+=sum;
        }

        ans=N;
        for(i=1;i<=n;i++) ans=getmin(ans,pre[i]+post[i]);
        printf("%lld\n",ans);
    }
    return 0;
}

 

切比雪夫距离

想不到 数学太差 做题太少

对于两点(x1,y1) (x2,y2)

dis = max(x2-x1,y2-y1) = ( |(x2-x1)+(y2-y1)| + |(x2-x1)-(y2-y1)| ) / 2 = ( |(x2+y2)-(x1+y1)| + |(x2-y2)-(x1-y1)| ) / 2

注:x2-x1>=0 y2-y1>=0

这样就把求(x1,y1) (x2,y2)之间切比雪夫距离转换为求(x1+y1,x1-y1) (x2+y2,x2-y2)之间曼哈顿距离的问题

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=0x3f3f3f3f3f3f3f3f;

struct node
{
    ll x,y;
    int id;
};

node point[100010];
ll pre[100010],post[100010];
int n;

bool cmpI(node n1,node n2)
{
    return n1.x<n2.x;
}

bool cmpII(node n1,node n2)
{
    return n1.y<n2.y;
}

ll getmin(ll a,ll b)
{
    if(a<b) return a;
    else return b;
}

int main()
{
    ll i,x,y,sum,ans;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            point[i].id=i;
            scanf("%lld%lld",&x,&y);
            point[i].x=x+y,point[i].y=x-y;
        }
        memset(pre,0,sizeof(pre));
        memset(post,0,sizeof(post));

        sort(point+1,point+n+1,cmpI);
        sum=0;
        for(i=2;i<=n;i++)
        {
            sum+=(i-1)*(point[i].x-point[i-1].x);
            pre[point[i].id]+=sum;
        }
        sum=0;
        for(i=n-1;i>=1;i--)
        {
            sum+=(n-i)*(point[i+1].x-point[i].x);
            post[point[i].id]+=sum;
        }

        sort(point+1,point+n+1,cmpII);
        sum=0;
        for(i=2;i<=n;i++)
        {
            sum+=(i-1)*(point[i].y-point[i-1].y);
            pre[point[i].id]+=sum;
        }
        sum=0;
        for(i=n-1;i>=1;i--)
        {
            sum+=(n-i)*(point[i+1].y-point[i].y);
            post[point[i].id]+=sum;
        }

        ans=N;
        for(i=1;i<=n;i++) ans=getmin(ans,pre[i]+post[i]);
        printf("%lld\n",ans/2);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值