洛谷 P1648看守 题解

题目描述

给出 d d d 维空间的 n n n 个点,求曼哈顿距离最大的两个点的曼哈顿距离。

两个 d d d 维的点 ( x 1 , x 2 , … , x d ) (x_1,x_2,\ldots,x_d) (x1,x2,,xd) ( y 1 , y 2 , … , y d ) (y_1,y_2,\ldots,y_d) (y1,y2,,yd) 的曼哈顿距离定义为 ∣ x 1 − y 1 ∣ + ∣ x 2 − y 2 ∣ + … + ∣ x d − y d ∣ |x_1-y_1|+|x_2-y_2|+\ldots+|x_d-y_d| x1y1+x2y2++xdyd

输入格式

第一行两个整数 n n n d d d
接下来 n n n 行,每行 d d d 个整数描述一个点的坐标。

输出格式

输出最大的曼哈顿距离。

题解

对于x与y之间的曼哈顿距离,是不是等于y到起点1的曼哈顿距离减去x到起点1的曼哈顿距离?

对于x与z之间的曼哈顿距离,是不是等于z到起点2的曼哈顿距离减去x到起点2的曼哈顿距离?

所以我们就可以算出来距离起点1最小的曼哈顿距离和距离起点1最大的曼哈顿距离之间的差,然后将这个同距离起点2最小的曼哈顿距离和距离起点2最大的曼哈顿距离之间的差相比较,取最大值。

这样即为二维的解。所以以此类推,在三维状态下,有四种情况,在四维状态下,作为一个三维生物,我是真的想象不出来有几种,我姑且猜想有八种情况(虽然我只考虑四种情况也过了,可能是数据正好吧 ),但是严谨一点来说,枚举所以第四维的情况的话是有八种的。这点欢迎大佬留言讨论一下。

所以代码如下

#include<bits/stdc++.h>
#define ll long long
ll start=0x7fffffff;
using namespace std;
ll read(){
    ll x=0,f=1; char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
ll x[]={-start,-start,-start,-start,-start,-start,-start,-start};
ll y[]={-start,start,start,-start,-start,start,start,-start};
ll z[]={-start,-start,start,start,-start,-start,start,start};
ll ls[]={-start,-start,-start,-start,start,start,start,start};
ll a[10];
ll sum[10];
ll maxx[10];
ll minn[10];
ll ans;
ll n,d;
int main()
{
    cin>>n>>d;
/*  if(d==4)
    {
        //cout<<"我想象不出四维";
        return 0;
    }*/
    for(ll i=1;i<=n;i++)
    {
        for(ll j=1;j<=d;j++)
        {
            a[j]=read();//用cin直接超时,不要问我怎么知道的
        }
        for(ll j=0;j<8;j++)
        {
            sum[j]=0;
        }
        for(ll j=0;j<8;j++)
        {
            sum[j]=sum[j]+abs(a[1]-x[j])+abs(a[2]-y[j])+abs(a[3]-z[j])+abs(a[4]-ls[j]);
        }
        for(ll j=0;j<8;j++)
        {
            if(sum[j]>maxx[j])
            {
                maxx[j]=sum[j];
            }
            if(sum[j]<minn[j]||minn[j]==0)
            {
                minn[j]=sum[j];
            }
            if(ans<maxx[j]-minn[j])
            {
                ans=maxx[j]-minn[j];
            }
        }
    }
    cout<<ans;
    return 0;
}

以及在线求大佬给估一下时间复杂度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值