美团2024届秋招笔试第三场第一题

想问一下哪里有问题,感觉自己的逻辑没问题,自己输入的好几个测试都正确
平均数为k的最长连续子数组
给定n个正整数组成的数组,求平均数正好等于
k 的最长连续子数组的长度。
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 256M,其他语言512M
输入描述:
第一行输入两个正整数n和k,用空格隔开。
第二行输入n个正整数a_i,用来表示数组。
输出描述:
如果不存在任何一个连续子数组的平均数等于k,则输出-1。
否则输出平均数正好等于 k 的最长连续子数组的长度。

示例1
输入例子:
5 2
1 3 2 4 1
输出例子:
3
例子说明:
取前三个数即可,平均数为2。

img

它不是有一个用例没有通过告诉你了,在下面么,你复制完全,贴出来看

你的代码主要问题在于你的代码没有考虑到连续子数组的情况。
你的代码在循环中计算了前缀和 d,并检查了 (d % l == 0)(d / l == b) 来判断是否满足条件。这个方法只适用于数组中只包含正整数的情况。但是,这个问题要求找到最长连续子数组,你的代码没有考虑连续性。在连续子数组的情况下,前缀和不是一个合适的方法。你可以使用滑动窗口来解决这个问题。
以下是经过修改的代码:

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

int main() {
    long n, k;
    cin >> n >> k;
    
    vector<long> arr(n);
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    
    long long sum = 0;
    long maxLen = -1;
    long left = 0;
    
    for (int right = 0; right < n; right++) {
        sum += arr[right];
        
        while ((sum * 1.0 / (right - left + 1)) > k) {
            sum -= arr[left];
            left++;
        }
        
        if ((sum * 1.0 / (right - left + 1)) == k) {
            maxLen = max(maxLen, right - left + 1);
        }
    }
    
    if (maxLen == -1) {
        cout << -1 << endl;
    } else {
        cout << maxLen << endl;
    }
    
    return 0;
}

这个代码使用了滑动窗口技巧,通过维护一个窗口的左边界 left 和右边界 right,以及当前窗口内元素的和 sum,来动态计算子数组的平均值,从而找到最长连续子数组的长度。这个代码应该能够正确解决问题。

引用 皆我百晓生 小程序回复内容作答:

感觉你的代码逻辑有一些问题,以下是我发现的问题和修改建议:

  1. 在第一个for循环中,数组c的下标应该从0开始,而不是从1开始。所以循环应该是从i=0开始,循环条件是i < a。
  2. 在第一个for循环中,对数组c的输入应该使用cin,而不是scanf。所以应该是cin >> c[i]。
  3. 在第二个for循环中,计算平均值的方式有错误。应该是d / l,而不是d / 1。
  4. 在第二个for循环中,判断平均值是否等于k的条件有问题。应该是d / l == b,而不是 (d % 1 == 0) && (d / 1 == b)。
  5. 在第二个for循环中,循环变量l的范围应该是从1到a,而不是从1到a-1。
  6. 在第二个for循环中,应该在找到平均值等于k的情况下,记录最长子数组的长度,并在循环结束后输出结果。

以下是修改后的代码:

#include <iostream>
using namespace std;

int main() {
    int n, k;
    int nums[20000];
    cin >> n >> k;
    for (int i = 0; i < n; i++){
        cin >> nums[i];
    }

    int start = 0;
    int end = 0;
    int sum = 0;
    int maxLen = -1;
    while (end < n) {
        sum += nums[end];
        if ((end - start + 1 > maxLen) && (sum * 1.0 / (end - start + 1) == k)) {
            maxLen = end - start + 1;
        }
        if (sum * 1.0 / (end - start + 1) < k) {
            sum -= nums[start];
            start++;
        }
        end++;
    }

    cout << maxLen << endl;
    
    return 0;
}

这样修改后的代码应该能够正确求解平均数为k的最长连续子数组的长度。