2023百度之星初赛第二场

发布时间 2023-09-26 12:56:52作者: chfychin

1. BD202309 星际航行(贪心)

题目描述:

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

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

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

每一艘飞船可以看做三维空间上的一个点,第i艘飞船可以用三维坐标 \((x_i,y_i,z_i)\) 表示。排布成连续的直线的n艘飞船坐标应该满足如下条件:这些点坐标中有两个维度相同,剩下一个维度应该组成一个连续的整数数列。例如,当\(x_1=x_ 2=…=x_n\)\(y_1=y_2=…=y_n\)\(∣z_i−z_ {i−1}∣=1\)(i=2…n)时,可以认为这些点处于一条连续的直线状态。注意,上述样例中是 n 个点的 x,y 维度坐标相同,也可以是y,z 维度坐标相同或者 x,z 维度坐标相同。另外,飞船最终的排列顺序与输入顺序无关。

由于飞船在宇宙中航行受到此地星空的约束,任何时刻飞船只能沿着三个维度中的一个维度飞行,每移动一个单位,会消耗一个单位的能源。

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

格式

输入:第 1 行,输入的是整n\((1≤n≤10^5)\);接下来的 n 行分别包含三个数字,表示每艘飞船的坐标,x,y,z\((−10^6≤x,y,z≤10^6)\)
输出:一行一个数字,表示最少消耗多少能源。

样例

输入: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>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr)
#define fi first
#define se second
#define int long long
#define YES "YES\n"
#define NO "NO\n"
#define Yes "Yes\n"
#define No "No\n"
#define yes "yes\n"
#define no "no\n"
#define Mod 998244353
#define mod 1000000007
#define pi 3.14159

using namespace std;

const int N = 1e5 + 10;

int x[N], y[N], z[N];
int n,ans;

int cal(int a[])//计算单点代价
{
	int ans = 0;
	int l = 1, h = n;
	while(l <h)
		ans = ans + abs(a[l ++] - a[h --]);
	return ans;
}

void solve()
{
	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);
	ans = cal(x) + cal(y) + cal(z);
	int l = 1, h = n;
	while(l < h)
		ans -= h-- - l ++;
	//扣除直线代价空缺,0->35=0->34+34->35,184->35=184->36+36->35
	//前面ans是直线到中心,可以看成ans->边界+边界->中心
	//现在扣除的是边界->中心
	cout << ans << '\n';
}

signed main() {
    IOS;
    int _ = 1;
    // cin >> _;
    while(_ --)
        solve();
    return _ ^ _;
}