2023年百度之星题解

BD202309星际航行

在深邃的宇宙中,星际舰队从地球出发,向未知的星际深渊进发。这支舰队是由最新科技的结晶,由 nn 艘星际飞船组成,每一艘飞船都像一颗璀璨的星辰,静静地驶过宇宙的深渊。

飞船的航行是静谧而神秘的,仿佛在宇宙中航行的幽灵,无声无息地穿行在星辰之间。然而,这静谧的星空并不安全,未知的危险随时可能来临。这就需要舰队成员们时刻保持警惕,如临大敌。

然而,这次航行并没有像预期的那样顺利。在舰队深入星空的某个地方,收到来自地球检测装置的警报,舰队已经进入外星文明的探测区域,舰队希望排布成一条连续的直线以减少舰队被外星文明探测到的可能。

每一艘飞船可以看做三维空间上的一个点,第ii艘飞船可以用三维坐标 (x_i,y_i,z_i)(xi​,yi​,zi​) 表示。排布成连续的直线的nn艘飞船坐标应该满足如下条件:这些点坐标中有两个维度相同,剩下一个维度应该组成一个连续的整数数列。例如,当x_1=x_2=…=x_nx1​=x2​=…=xn​且y_1=y_2=…=y_ny1​=y2​=…=yn​且|z_i-z_{i-1}|=1∣zi​−zi−1​∣=1(i=2…ni=2…n)时,可以认为这些点处于一条连续的直线状态。注意,上述样例中是 nn 个点的 x,yx,y 维度坐标相同,也可以是 y,zy,z 维度坐标相同或者 x,zx,z 维度坐标相同。另外,飞船最终的排列顺序与输入顺序无关。
由于飞船在宇宙中航行受到此地星空的约束,任何时刻飞船只能沿着三个维度中的一个维度飞行,每移动一个单位,会消耗一个单位的能源。

尽管情况紧急,舰队仍然需要为后续的航行做准备。作为舰队成员之一的你,需要给出舰队排成一条连续的直线最少消耗多少能源。

格式

输入格式:

第 11 行,输入的是整数 nn(1 \le n \le 10^51≤n≤105);
接下来的 nn 行分别包含三个数字,表示每艘飞船的坐标,x,y,z(-10^6 \le x,y,z \le 10^6)x,y,z(−106≤x,y,z≤106) 。

输出格式:

一行一个数字,表示最少消耗多少能源。

样例 1

输入:

3
2 0 2
6 35 -87
0 184 -126

输出:

316
备注

样例解释:可行的一组方案为:
把所有点的x移动到2,代价为|2-2|+|6-2|+|0-2|=6;
把所有点的y移动到区间[34,36],代价为|0-34|+|35-35|+|184-36|=182;
把所有点的z移动到区间-87,代价为|-87-2|+|-87-(-87)|+|-87-(-126)|=128;
总代价为:6+182+128=316。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int x[N],y[N],z[N];
int n;
ll cal(int a[]){//计算单点代价
    ll v=0;
    int low=1,high=n;
    while(low<high){
        v=v+abs(a[low++]-a[high--]);
    }
    return v;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x[i]>>y[i]>>z[i];

    }
    auto f=[](int a,int b){return a<b;};
    sort(x+1,x+n+1,f);
    sort(y+1,y+n+1,f);
    sort(z+1,z+n+1,f);
    ll res=cal(x)+cal(y)+cal(z);
    int low=1,high=n;
    while(low<high){
        //扣除直线代价空缺,0->35=0->34+34->35;184->35=284->36+36->35;
        //前面res是直线到中心,可以看成res->边界+边界->中心
        //现在扣除的是边界->中心
        res-=high-- - low++;
    
    }
    cout<<res<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_71356343/article/details/132410710