专栏文章

2025-10-16模拟赛总结

生活·游记参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minldxj0
此快照首次捕获于
2025/12/02 04:18
3 个月前
此快照最后确认于
2025/12/02 04:18
3 个月前
查看原文

前言

最惨的一次……呜呜呜😱😱😱
考的实在是太好了
成绩高达 10+30+30+10=8010 + 30 + 30 + 10 = 80 😣
我的 44 倍都没有某些巨佬高😫

A

zrr 题。这个人没有处理剩下的 ?,喜挂 9090 分。绝对是 SPJ 的问题,题目里都没有说不能留 ? 🙁
很容易发现一种最优策略:
  1. 先将原有已经匹配的左右括号抵消。
  2. 对于 ?,若左边有多余的 (,则将 ? 改为 ),抵消;若没有,则看右边是否有多余的 ),有的话将 ? 改为 (,抵消。
  3. 将剩余的 ?()()() 的方式赋值,若数量是奇数,则剩下的那个 ? 随便改。
直接模拟即可。
代码CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int _, n, m, k[N];
bool f[N];
string s;
int main() {
  cin.tie(0)->sync_with_stdio(0);
  for (cin >> _; _; _--) {
    cin >> n >> s, s = " " + s, k[0] = 0, m = n;
    fill(f + 1, f + n + 1, 0);
    for (int i = 1; i <= n; i++)
      s[i] == '(' ? k[++k[0]] = i : s[i] == ')' && k[0] && (f[i] = f[k[k[0]--]] = 1, m -= 2);
    k[0] = 0;
    for (int i = 1; i <= n; i++)
      !f[i] && (s[i] == '(' ? k[++k[0]] = i : (s[i] == ')' ? k[0] && (f[i] = f[k[k[0]--]] = 1, m -= 2) : k[0] && (f[i] = f[k[k[0]--]] = 1, s[i] = ')', m -= 2)));
    k[0] = 0;
    for (int i = n; i; i--)
      !f[i] && (s[i] == ')' ? k[++k[0]] = i : (s[i] == '(' ? k[0] && (k[0]--, m -= 2) : k[0] && (s[i] = '(', k[0]--, m -= 2)));
    k[0] = 0;
    for (int i = 1; i <= n; i++)
      s[i] == '?' && (k[0] ? s[k[k[0]--]] = '(', s[i] = ')', m -= 2 : k[++k[0]] = i);
    for (int i = 1; i <= n; i++)
      s[i] == '?' && (s[i] = '(');
    cout << m << "\n" << s.substr(1) << "\n";
  }
  return 0;
}

B

直接状压,fif_i 表示已经选了的字符串状态为 ii 的合法前缀数量。可是不知道为什么我写的状压 WA 了,只有 3030 分,改成了某些巨佬的写法才 A。
代码CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int n, k[N], r[N], v, f[1 << N];
unordered_map<int, int> d[N];
int main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> n;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    for (char c : s) {
      r[i] = min(r[i], k[i] += (c == '(') - (c == ')'));
      k[i] <= r[i] && (d[i][k[i]]++);
    }
  }
  for (int i = 1; i < (1 << n); i++) {
    int s = 0;
    for (int j = 0; j < n; j++)
      (i >> j) & 1 && (s += k[j]);
    f[i] = -1;
    for (int j = 0; j < n; j++)
      if ((i >> j) & 1 && ~f[i ^ (1 << j)]) {
        int h = s - k[j], w;
        h >= 0 && (v = max(v, w = f[i ^ (1 << j)] + d[j][-h]), r[j] + h >= 0 && (f[i] = max(f[i], w)));        
      }
  }
  cout << v;
  return 0;
}

C

最后 55 分钟打的暴力,拼尽全力无法战胜了😦

D

暴推 2.5h 公式无果,结果最后 4040 分暴力都没有调出来🙄
生无可恋了……

后记

这次终于也是考了一次倒数了啊啊啊啊

评论

0 条评论,欢迎与作者交流。

正在加载评论...