AcWing 4114. 垃圾桶

该问题要求计算所有房子主人倒垃圾需要行走的总距离,基于给定的01字符串确定垃圾桶位置。解决方案是通过两次遍历找到每个位置左右最近的垃圾桶,然后计算总距离。C++代码实现了一个线性时间复杂度的算法,通过预处理避免了超时。
摘要由CSDN通过智能技术生成

原题链接: AcWing 4114. 垃圾桶
题目来源:AcWing 夏季每日一题2023

一条很长的街道上有 N 个房子。

第一个房子在位置 1,第二个房子在位置 2,以此类推。

任意一对房子 ij 之间的距离为 |i−j|

一些房子的位置处有垃圾桶。

每个房子的主人都要倒垃圾。

如果自己房子前面有垃圾桶,则无需移动,直接倒垃圾即可。

如果自己房子前面没有垃圾桶,则前往距离自己最近的垃圾桶处倒垃圾,如果这样的垃圾桶不唯一,则任意前往一个即可。

请计算,所有房子的主人倒垃圾需要行走的总距离之和。

输入格式
第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含整数 N

第二行包含一个长度为 N 的 01 字符串,第 i 个字符如果为 1,则表示第 i 个房屋门前有垃圾桶,如果为 0 ,则表示第 i 个房屋门前没有垃圾桶。

输出格式
每组数据输出一个结果,每个结果占一行。

结果表示为 Case #x: y ,其中 x 为组别编号(从 1 开始),y 为所有房子的主人倒垃圾需要行走的总距离之和。

数据范围

  • 1≤T≤100,
  • 1≤N≤5×105,
  • 字符串中至少包含一个 1。

输入样例:

2
3
111
6
100100

输出样例:

Case #1: 0
Case #2: 5

样例解释
对于 Case 1,每个房子门前都有垃圾桶,所以大家都不用移动。

对于 Case 2,第 1,4
个房子的门前有垃圾桶,这两家主人不用移动,第 2
个房子的主人去第 1
个房子处倒垃圾,第 3,5,6
个房子的主人去第 2
个房子处倒垃圾。




方法一:枚举

思路:

  • 首先,n最大有5 * 105,假设极端情况,第一个一个是1,后面全是0,那么结果就是0+1+2+…+5 * 105,这是会爆int的,因此要用long long来存
  • 经过判断,必须采用O(n)的算法才能过
  • 开两个数组,l[i]存i左边最近的垃圾桶位置,r[i]存i右边最近的垃圾桶位置,则i的到垃圾桶的最近距离就是两个距离取min

C++ 代码:

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

const int maxn = 500010, INF = 1e8;
int n;
char s[maxn];
int l[maxn], r[maxn];

int main(){
    int T;
    scanf("%d", &T);
    
    for(int cases = 1; cases <= T; cases ++ ){  // 一共有t个询问
        scanf("%d", &n);
        scanf("%s", s);
        
        // 从左到右预处理 l[i]表示i左边最近的垃圾桶的位置 t为当前最近的垃圾桶的位置
        for(int i = 0, t = -INF; i < n; i ++ ){
            if(s[i] == '1') t = i;
            l[i] = t;
        }
        
        // 从右到左预处理 r[i]表示i右边最近的垃圾桶的位置 t为当前最近的垃圾桶的位置
        for(int i = n - 1, t = INF; i >= 0; i -- ){
            if(s[i] == '1') t = i;
            r[i] = t;
        }
        
        // 遍历一次得到结果 距离最近的取左右两边距离的min
        ll res = 0;
        for(int i = 0; i < n; i ++ ){
            res += min(i - l[i], r[i] - i);
        }
        
        printf("Case #%d: %lld\n", cases, res);	// 注意这个lld
    }
    
    
    return 0;
}

复杂度分析:

  • 时间复杂度:O(n),一共需要遍历数组3次,O(3n)也就是O(n)
  • 空间复杂度:O(n),开了两个辅助数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值