bluecode-优质章节的连续选择

87 阅读3分钟

问题描述

在番茄小说的书籍中,编辑小S正在寻找精彩的连续章节以进行特色展示。每个章节都有各自的文字数量,编辑希望选出的连续章节总字数不超过 k。在这些连续章节中,除了第一章和最后一章,任何字数多于前后章节的章节都被视为优质章节。编辑的目标是挑选出尽可能多的优质章节,同时满足总字数限制。如果有多个答案优质章节数相同,请输出总字数最少的答案。优质章节数和总字数均相同,则输出区间下标最小的答案。

例如,假设章节字数为 [1000, 3000, 2000, 4000, 3000, 2000, 4000, 2000],给定的字数上限 k 为 15000。一种优选方案是选择从第1章到第5章,其中第2章和第4章是优质章节。

输入:

  • n:章节数目
  • k:总字数上限
  • array_a:各个章节的字数

返回规则如下:

  • 返回一个字符串,格式为"优质章节数,优质章节数最多的区间左下标,优质章节数最多的区间右下标"

测试样例

样例1:

输入:n = 8,k = 15000,array_a = [1000, 3000, 2000, 4000, 3000, 2000, 4000, 2000]
输出:'2,1,5'

样例2:

输入:n = 8,k = 15000,array_a = [2000, 5000, 2000, 1000, 4000, 2000, 4000, 3000]
输出:'2,4,8'

样例3:

输入:n = 5,k = 10000,array_a = [3000, 4000, 1000, 5000, 2000]
输出:'1,1,3'

样例4:

输入:n = 6,k = 8000,array_a = [1000, 2000, 3000, 4000, 500, 2500]
输出:'1,3,5'

样例5:

输入:n = 10,k = 5000,array_a = [500, 1000, 1500, 500, 500, 1000, 1500, 500, 500, 1000]
输出:'1,2,4'

#include <climits>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

std::string solution(int n, int k, std::vector<int> array_a) {
  int max_quality = -1;
  int min_total = INT_MAX;
  int best_i = -1, best_j = -1;

  // Precompute prefix sums for efficient range sum calculation
  vector<int> prefix(n + 1, 0);
  for (int i = 0; i < n; ++i) {
    prefix[i + 1] = prefix[i] + array_a[i];
  }

  for (int i = 0; i < n; ++i) {
    for (int j = i; j < n; ++j) {
      int total = prefix[j + 1] - prefix[i];
      if (total > k) {
        continue;
      }
      int quality = 0;
      for (int m = i + 1; m < j; ++m) {
        if (array_a[m] > array_a[m - 1] && array_a[m] > array_a[m + 1]) {
          quality++;
        }
      }
      // Compare to find the best
      if (quality > max_quality) {
        max_quality = quality;
        min_total = total;
        best_i = i + 1; // converting to 1-based index
        best_j = j + 1;
      } else if (quality == max_quality) {
        if (total < min_total) {
          min_total = total;
          best_i = i + 1;
          best_j = j + 1;
        } else if (total == min_total) {
          if (i + 1 < best_i || (i + 1 == best_i && j + 1 < best_j)) {
            best_i = i + 1;
            best_j = j + 1;
          }
        }
      }
    }
  }
  return to_string(max_quality) + "," + to_string(best_i) + "," +
         to_string(best_j);
}

int main() {
  //  You can add more test cases here
  std::vector<int> array_a1 = {1000, 3000, 2000, 4000, 3000, 2000, 4000, 2000};
  std::vector<int> array_a2 = {2000, 5000, 2000, 1000, 4000, 2000, 4000, 3000};

  std::cout << (solution(8, 15000, array_a1) == "2,1,5") << std::endl;
  std::cout << (solution(8, 15000, array_a2) == "2,4,8") << std::endl;

  return 0;
}