2025/8/2 模拟赛总结

\(50+100+20+20=190\),第一题真的太抽象了

#A. 器材整理

比较抽象的题,显然在确定箱子大小确定后,可以 \(O(nk)\) 暴力 check,写个暴力打表发现答案大概有单调性,但是直接二分可以过所有大样例且过 \(10^4\) 组拍。

这时可以在二分出答案后向前寻找 \(300\) 个,找到答案直接输出即可

// BLuemoon_
#include <bits/stdc++.h>

using namespace std;

const int kMaxN = 1e3 + 5;

int T = 1, n, a[kMaxN], ans, k, L, R, cnt, vis[kMaxN], F = 1;

bool Chk(int x) {
  fill(vis + 1, vis + n + 1, 0);
  for (int i = 1; i <= k; i++) {
    int lst = x;
    for (int j = 1; j <= n; j++) {
      lst >= a[j] && !vis[j] && (vis[j] = 1, lst -= a[j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      return 0;
    }
  }
  return 1;
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  for (cin >> T; T; T--, cnt = 0, F = 1) {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
      cin >> a[i], cnt += a[i], i > 1 && (F &= a[i] == a[i - 1]);
    }
    if (k == 1) {
      cout << cnt << '\n';
      continue;
    }
    if (F) {
      cout << (n + k - 1) / k * a[1] << '\n';
      continue;
    }
    if (1ll * n * k * cnt <= 1e7) {
      sort(a + 1, a + n + 1, greater<int>());
      for (int i = 1; i <= cnt; i++) {
        if (Chk(i)) {
          ans = i;
          break;
        }
      }
      cout << ans << '\n';
      continue;
    }
    sort(a + 1, a + n + 1, greater<int>()), L = 1, R = cnt;
    for (int mid = L + R >> 1; L < R; mid = L + R >> 1) {
      Chk(mid) ? R = mid : L = mid + 1;
    }
    for (int i = max(1, L - 300); i <= L; i++) {
      if (Chk(i)) {
        ans = i;
        break;
      }
    }
    cout << ans << '\n';
  }
  return 0;
}

#B. 简单题

这个是真的简单题,正难则反。将所有问号填入 \(1\),求出答案。对于每一个连续的问号段,如果左右字符不同则修改不影响答案。如果左右都是 \(0\),则答案会减少 \(2\),按长度从小到大会更优。否则如果两边都是 \(1\),则答案会增加 \(2\),此时按长度从大到小会更优。使用 set 模拟即可

// BLuemoon_
#include <bits/stdc++.h>

using namespace std;
using Pii = pair<int, int>;

const int kMaxN = 2e5 + 5;

struct Cmp {
  bool operator()(const Pii &x, const Pii &y) const { return x.first != y.first ? x.first < y.first : (x.first == -2 ? x.second < y.second : (x.first == 2 ? x.second > y.second : x.second < y.second)); }
};

int T = 1, n, tot1, totq, ans[kMaxN], cur, cnt;
string s, t;
multiset<Pii, Cmp> st;

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  for (cin >> T; T; T--, tot1 = totq = 0, st.clear()) {
    cin >> n >> s, s = ' ' + s, fill(ans, ans + n + 1, -1), t = s, cnt = 0;
    for (int i = 1; i <= n; i++) {
      tot1 += s[i] == '1', totq += s[i] == '?', t[i] == '?' && (t[i] = '1');
    }
    for (int i = 1, pre = 1; i <= n; i++) {
      if (s[i] != '?') {
        if (pre <= i - 1) {
          if (s[pre - 1] != s[i]) {
            st.insert({0, i - pre});
          } else if (s[i] == '0') {
            st.insert({-2, i - pre});
          } else {
            st.insert({2, i - pre});
          }
        }
        pre = i + 1;
      }
    }
    for (int i = 1; i <= n; i++) {
      cnt += t[i] != t[i - 1];
    }
    ans[cur = totq + tot1] = cnt;
    for (auto u : st) {
      if (u.first == -2) {
        for (int i = 1; i < u.second; i++) {
          ans[--cur] = cnt;
        }
        ans[--cur] = (cnt -= 2);
      } else if (u.first == 0) {
        for (int i = 1; i <= u.second; i++) {
          ans[--cur] = cnt;
        }
      } else {
        ans[--cur] = (cnt += 2);
        for (int i = 2; i <= u.second; i++) {
          ans[--cur] = cnt;
        }
      }
    }
    for (int i = 0; i <= n; i++) {
      cout << ans[i] << " \n"[i == n];
    }
  }
  return 0;
}

#C. 异或可达

TBD...

#D. ABBA

TBD...

posted @ 2025-08-02 17:02  BluemoonQwQ  阅读(22)  评论(0)    收藏  举报