Loading

2022.10.18 总结

1. 逐月 P5074

逐月 P5074

题意

\(n\) 头奶牛,第 \(i\) 头奶牛的位置在 \(w_i\)

每头奶牛要么有斑点,要么没有。

对于在位置 \(i\) 的奶牛,它有没有斑点取决于在 \(n\) 头奶牛中和它距离最近的那头奶牛,如果那头奶牛有斑点,它就有,否则没有。

如果有很多头奶牛到它的距离最近,那么只要那些奶牛中有一头有斑点即可。

现在,位置 \(a\) 到位置 \(b\) 上每个位置都有一头奶牛,请问这些奶牛中有多少头奶牛有斑点。

思路

100 分

如果在位置 \(1\) 上有一头奶牛,位置 \(3\) 上面有一头奶牛,并且他们中间没有奶牛,那么位置 \(1 \sim 3\) 的奶牛是否有斑点就只和这两头奶牛有关。

所以,可以只枚举 \(n\) 头奶牛计算答案。

那么就要开始分类讨论了。

假设当前选的两头相邻奶牛编号为 \(i\)\(i + 1\)

  1. \(i\)\(i + 1\) 都有斑点,直接把区间内的所有奶牛全部加起来。

  2. \(i\)\(i + 1\) 都没有斑点,直接进入下一次循环。

  3. \(i\) 有斑点,\(i + 1\) 没有,从他们的等分点往右的都是斑点牛。

  4. \(i\) 没有,\(i + 1\) 有斑点,从他们的等分点往左的都是斑点牛。

直接模拟即可。

但是有一个小细节:这 \(n\) 头奶牛可能会被算两遍,所以要先预处理出这 \(n\) 个点中可行的点,在模拟时忽略这 \(n\) 个点即可。

时间复杂度

枚举 \(n\) 头奶牛,\(O(n)\)

空间复杂度

记录所有奶牛,\(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 50010;

int n, a, b, cnt;
string s;

struct cow{
  bool f;
  int w;
} c[N];

bool cmp(const cow &i, const cow &j){  // 按照位置排序
  return i.w < j.w;
}

void F(int l, int r){  // 更新斑点牛数量
  cnt += max(0, min(r, b) - max(l, a) + 1);
}

int main(){
  freopen("learning.in", "r", stdin);
  freopen("learning.out", "w", stdout);
  cin >> n >> a >> b;
  int m = 0;
  for (int i = 1; i <= n; i++) {
    cin >> s >> c[i].w;
    c[i].f = (s == "S");
    cnt += (c[i].f && c[i].w >= a && c[i].w <= b);  // 预处理出可行的斑点奶牛
  }
  sort(c + 1, c + n + 1, cmp);
  c[0] = {c[1].f, 1};
  c[n + 1] = {c[n].f, int(1e9)};
  for (int i = 0; i <= n; i++) {
    if (c[i].f && c[i + 1].f) {
      F(c[i].w + 1, c[i + 1].w - 1);
    } else if (c[i].f) {
      F(c[i].w + 1, (c[i].w + c[i + 1].w) / 2);
    } else if (c[i + 1].f) {
      F((c[i].w + c[i + 1].w + 1) / 2, c[i + 1].w - 1);
    }
  }
  cout << cnt;
  return 0;
}
posted @ 2023-03-02 22:43  chengning0909  阅读(9)  评论(0编辑  收藏  举报