mobile wallpaper 1
842 字
2 分钟
牛客周赛 Round 131
2026-02-16

☁️体验#

My First AK! 但是vp

💡题解#

A - ICPC Balloons#

题意#

给出一个大写字符 c{A,B,C,D}c∈\{‘A’,‘B’,‘C’,‘D’\},表示通过题目的题号。要求输出相应的气球颜色 s{red,orange,blue,green}s∈\{‘red’,‘orange’,‘blue’,‘green’\}

思路#

按题意模拟即可。

代码#

void solve()
{
vector<string> s = {"red","orange","blue","green"};
char c;
cin >> c;
D(s[c - 'A']);
}

B - String Covering#

题意#

你有一个长度为 nn 的初始全 000101 字符串,你可以执行任意次操作:

  • 选择两个相邻的位置,将这两个位置都变成 11

判断能否通过操作将这个字符串变成长度同样为 nn 的目标字符串 ss

思路#

显然,我们可以创造的最短连续全 11 子串长度为 22,如果 ss 中有长度为 11 的全 11 子串,那必定无法完成。

因此,遍历统计每个连续全 11 子串长度,在这个过程中进行判断即可。

代码#

void solve()
{
int n;
cin >> n;
string s;
cin >> s;
s += '0';
int t = 0;
for(int i = 0; i <= n; i++)
if(s[i] == '1') t++;
else if(t == 1)
{
NO;
return;
}
else t = 0;
YES;
}

C - Get The Sequence#

题意#

你有一个长度为 nn 的序列 a1,a2,,ana_1,a_2,…,a_n​,和一个长度为 mm 的序列 b1,b2,,bmb_1,b_2,…,b_m​,每个元素都是正整数。

你可以执行任意次操作:

  • 删除 aa11 个元素
  • aa 中的 11 个元素大小减少 11

判断是否可以通过操作将 aa 变成 bb

思路#

很明显,如果每个 bib_i 的对应位置上都有一个大于等于它的 aia_i 就行了。

双指针模拟即可。

代码#

void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(n), b(m);
vcin(a);
vcin(b);
int l = 0, r = 0;
while(l < n && r < m)
{
while(l < n && a[l] < b[r]) l++;
if(l == n) break;
l++, r++;
}
if(r == m) YES;
else NO;
}

D - Longest Subsequence#

题意#

你有一个长度为 nn 的序列 a1,a2,,ana_1,a_2,…,a_n​,从中选出一个子序列,使得选出的子序列中任意相邻两个元素的差的绝对值恰好为 11

问最长子序列的长度是多少?

思路#

简单 DPDP 简单做。

fif_i 表示以 ii 结尾的最长子序列的长度,那么我们容易得出以下关系:

fi=max(fi1,fi+1)+1f_i = \max(f_{i - 1}, f_{i + 1}) + 1

代码#

void solve()
{
input(n, a);
int ans = 0;
unordered_map<int, int> f;
for(int& i : a)
{
f[i] = max(f[i - 1], f[i + 1]) + 1;
ans = max(ans, f[i]);
}
D(ans);
}

E - Eat The Candy#

题意#

你有 nn 个盒子,盒子里糖果的数量分别是 a1,a2,,ana_1,a_2,…,a_n

你可以执行任意次操作:

  • 选择相邻的两个盒子,各吃掉 11 颗糖,然后得到 11 颗新糖,并选择任意一个盒子放入

问最后糖最多的盒子里面有多少糖?

思路#

显然,选择 aia_i 为不动的盒子,把前面和后面的盒子的贡献全部加到 aia_i 里面,这种做法是最优的。

计算前缀贡献和以及后缀贡献和,然后遍历每个位置更新答案最大值即可。

代码#

void solve()
{
input(n, a);
if(n == 1)
{
D(a[0]);
return;
}
vector<int> pre(n), suf(n), t = a;
for(int i = 1; i < n; i++)
{
int d = min(t[i - 1], t[i]);
pre[i] = pre[i - 1] + d;
t[i] -= d;
}
t = a;
for(int i = n - 2; i >= 0; i--)
{
int d = min(t[i], t[i + 1]);
suf[i] = suf[i + 1] + d;
t[i] -= d;
}
int ans = 0;
for(int i = 0; i < n; i++)
ans = max(ans, pre[max(i - 1, 0LL)] + a[i] + suf[min(i + 1, n - 1)]);
D(ans);
}

F - Bracket Coloring#

题意#

给你一个长度为 nn、仅由字符 (‘(’)‘)’ 组成的括号序列 ss,且保证这是一个合法括号序列。

现在你要给每个括号染上红色或蓝色,但需要满足以下条件:

  • 每一对相互匹配的括号必须染上相同的颜色
  • 若序列中两个相邻位置的括号字符相同,则它们的颜色不能相同。

问有多少种不同的染色方案,对 998244353998 244 353 取模后输出。

思路#

给每对括号编号,如果相邻两个位置颜色不能相同,那么就把这两个编号连一条边,最后对于每一个连通分量,都是一个二分图染色问题。

设连通分量的个数为 kk

那么,最后答案就是 2kmod9982443532 ^ k \mod 998 244 353

代码#

void solve()
{
int n;
cin >> n;
string s;
cin >> s;
stack<int> stk;
vector<int> f(n);
int id = 0;
for(int i = 0; i < n; i++)
if(s[i] == '(') stk.push(i);
else
{
f[stk.top()] = f[i] = ++id;
stk.pop();
}
DSU d(id);
for(int i = 1; i < n; i++)
if(s[i - 1] == s[i])
d.merge(f[i - 1], f[i]);
int ans = qpow(2, d.countKunion(1), mod);
D(ans);
}

🎈模板#

快速幂#

int qpow(int a, int b, int m) {
int res = 1;
for ( ; b; b /= 2, a = a * a % m)
if (b % 2)
res = res * a % m;
return res;
}

并查集#

struct DSU {
vector<int> f, siz;
int n;
DSU() {}
DSU(int _n) {
n = _n;
init(n);
}
void init(int n) {
f.resize(n + 1);
iota(f.begin(), f.end(), 0);
siz.assign(n + 1, 1);
}
int find(int x) {
return f[x] == x ? x : f[x] = find(f[x]);
}
void merge(int x, int y) {
x = find(x), y = find(y);
if (x == y)
return;
f[y] = x;
siz[x] += siz[y];
}
bool same(int x, int y) {
return find(x) == find(y);
}
int size(int x) {
return siz[find(x)];
}
int countKunion(int k) {
int res = 0;
for (int i = 1; i <= n; i++)
if (find(i) == i && siz[i] >= k)
res++;
return res;
}
};

头文件#

#include <bits/stdc++.h>
#define vvcin(_x) for(auto& _e : _x) for(auto& _i : _e) cin >> _i
#define vcin(_x) for(auto& _i : _x) cin >> _i
#define input(_T, _n, _a) int _n; cin >> _n; vector<_T> _a(_n); vcin(_a)
#define D(_x) cout << _x << endl
#define vD(_x) for(int _i = 0; _i < _x.size(); ++_i) cout << (_x[_i]) << " \n"[_i == _x.size() - 1]
#define vvD(_x) for(auto& _e : _x) vD(_e)
#define vcin1(_x) for(int _i = 1; _i < _x.size(); ++_i) cin >> _x[_i]
#define input1(_T, _n, _a) int _n; cin >> _n; vector<_T> _a(_n + 1); vcin1(_a)
#define D1(_x) cout << "# " << _x << endl
#define vD1(_x) for(int _i = 1; _i < _x.size(); ++_i) cout << (_x[_i]) << " \n"[_i == _x.size() - 1]
#define YES cout << "YES" << endl
#define NO cout << "NO" << endl
#define Yes cout << "Yes" << endl
#define No cout << "No" << endl
#define yes cout << "yes" << endl
#define no cout << "no" << endl
#define all(_x) _x.begin(), _x.end()
#define rall(_x) _x.rbegin(), _x.rend()
#define INF LLONG_MAX
#define inf INT_MAX
#define endl '\n'
#define int long long
using namespace std;
typedef long long ll;
constexpr int MOD = 1000000007;
constexpr int mod = 998244353;
void solve()
{
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int _ = 1;
cin >> _;
while (_--)
solve();
return 0;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

牛客周赛 Round 131
https://blog.hycode.qzz.io/posts/nk-weekly-131/post/
作者
Hycode
发布于
2026-02-16
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录