上海计算机学会 2023年11月月赛 丙组T5 推箱子(数学 思维 排序)

文章讲述了将推箱子问题转化为坐标移动问题,通过计算每个箱子到目标位置的距离得出最少移动次数,给出了C++代码示例。
摘要由CSDN通过智能技术生成

第五题:T5推箱子

标签:排序、数学、思维
题意:给定 t t t组数据,每组数据给定长度为 n n n的字符串, @ @ @表示箱子, _ \_ _表示空格,求把箱子都推到一起(即两两箱子之间没有空格),最少移动次数。
题解:我们稍微把题意变下,给定 n n n个点在 x x x轴上的的坐标,求把这些点移到同一个位置的最少移动次数。
举个例子(坐标): 3   5   8   10 3 \ 5 \ 8 \ 10 3 5 8 10


如果把这些点都移到 2 2 2的坐标,移动次数为: 1 + 3 + 6 + 8 = 18 1+3+6+8=18 1+3+6+8=18
如果把这些点都移到 3 3 3的坐标,移动次数为: 0 + 2 + 5 + 7 = 14 0+2+5+7=14 0+2+5+7=14
如果把这些点都移到 5 5 5的坐标,移动次数为: 2 + 0 + 3 + 5 = 10 2+0+3+5=10 2+0+3+5=10
如果把这些点都移到 6 6 6的坐标,移动次数为: 3 + 1 + 2 + 4 = 10 3+1+2+4=10 3+1+2+4=10
如果把这些点都移到 8 8 8的坐标,移动次数为: 5 + 3 + 0 + 2 = 10 5+3+0+2=10 5+3+0+2=10
会发现把点移到这些点中最中间那个点,移动次数最少,推箱子问题同理,只不过得去考虑每个箱子会占一个位置,在中间位置( k k k)左边的第一个箱子推到 k − 1 k-1 k1的位置,其他的同理,即对于第 i i i 个箱子来说,需要移动的距离为 a[k] - a[i] - (k-i)(i<k);在中间位置右边的第 i i i个箱子,同理,需要移动的距离为 a[i] - a[k] - (i-k)(i>k)。

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
string s;
ll a[1000005];

int main() {
    ll t, n;
    cin >> t;
    while (t--) {
        cin >> n >> s;
        ll c = 0, ans = 0;
        for (int i = 0; i < n; i++) {
            if (s[i] == '@') a[++c] = i;
        }
        sort(a + 1, a + 1 + c);
        ll k = (c + 1) / 2;
        for (int i = 1; i <= c; i++) {
            if (i < k) ans += (a[k] - a[i] - (k - i));
            else ans += (a[i] - a[k] - (i - k));
        }
        cout << ans << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值