Loading

2022.10.17 总结

1.逐月 P5000

逐月 P5000

题意

有一个长度为 \(n\)\(01\) 字符串,令 \(d\)\(\min \{i - j\}\) \((s_i = 1, s_j = 1, j < i)\)

现在需要将两个 \(0\) 改成 \(1\),请求出最大的 \(d\)

思路

100 分

先来两个函数。

int Mind(string p){  // 最小间隔
  string t = p;
  int last = -1, mind = n + 1;
  for (int i = 0; i < n; i++) {
    if (t[i] == '1') {
      if (last == -1) {
        last = i;
      } else {
        mind = min(mind, i - last);
        last = i;
      }
    }
  }
  return (mind == n + 1 ? -1 : mind);
}

int Maxd(string p){  // 最大间隔
  string t = p;
  int last = -1, maxd = -1;
  for (int i = 0; i < n; i++) {
    if (t[i] == '1') {
      if (last == -1) {
        last = i;
      } else {
        maxd = max(maxd, i - last);
        last = i;
      }
    }
  }
  return maxd;
}

需要分类讨论两个 \(1\) 的位置。

  • 最左边和最右边
int len1(){
  string t = s;
  if (t[0] == '1' || t[n - 1] == '1') {
    return -1;
  }
  t[0] = t[n - 1] = '1';
  return Mind(t);
}
  • 最左边一个,中间一个
int len2(){
  string t = s;
  if (t[0] == '1') {
    return -1;
  }
  t[0] = '1';
  return min(Mind(t), Maxd(t) / 2);
}
  • 最右边一个,中间一个
int len3(){
  string t = s;
  if (t[n - 1] == '1') {
    return -1;
  }
  t[n - 1] = '1';
  return min(Mind(t), Maxd(t) / 2);
}
  • 最长区间 \(3\) 等分点
int len4(){
  return min(Mind(s), Maxd(s) / 3);
}
  • 最长区间等分点和次长区间等分点
int len5(){
  int last = -1, d1 = 0, d2 = 0;
  for (int i = 0; i < n; i++) {
    if (s[i] == '1') {
      if (last == -1) {
        last = i;
      } else {
        if (i - last > d1) {
          d2 = d1, d1 = i - last;
        } else {
          d2 = max(d2, i - last);
        }
        last = i;
      }
    }
  }
  return (!d2 ? -1 : min(Mind(s), d2 / 2));
}

时间复杂度

每个函数都是 \(O(n)\),总时间复杂度为 \(O(n)\)

空间复杂度

长度为 \(n\) 的字符串,\(O(n)\)

posted @ 2023-03-02 22:42  chengning0909  阅读(7)  评论(0编辑  收藏  举报