当前位置: 首页 > news >正文

AtCoder Beginner Contest 458 ABCDE

A - Chompers

  • 预估难度:入门
  • 标签:字符串

题意

给定一个由小写英文字母组成的字符串 \(S\) 以及一个正整数 \(N\)。字符串 \(S\) 的长度至少为 \(2N+1\)

请删除 \(S\) 的开头的 \(N\) 个字符以及末尾的 \(N\) 个字符,将剩余字符串输出。

代码

void solve()
{string s;int n;cin >> s >> n;cout << s.substr(n, s.size() - 2 * n);
}

B - Count Adjacent Cells

  • 预估难度:入门
  • 标签:枚举

题意

有一张 \(H\)\(W\) 列的网格图。从上往下数第 \(i\) 行、从左往右数第 \(j\) 列的单元格记作单元格 \((i, j)\)

\(|x_1 - x_2| + |y_1 - y_2| = 1\) 时,称单元格 \((x_1, y_1)\)\((x_2, y_2)\)边相邻的。

请对每一个单元格,求出与其边相邻的单元格的数量。

思路

枚举每个单元格,然后判断上下左右四个单元格中有多少个位于网格内部。

代码

int n, m;// 检查坐标 (x, y) 是否在地图内
bool check(int x, int y)
{return x >= 1 && x <= n && y >= 1 && y <= m;
}void solve()
{cin >> n >> m;for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){cout << check(i - 1, j) +check(i + 1, j) +check(i, j - 1) +check(i, j + 1)   << " ";}cout << "\n";}
}

C - C Stands for Center

  • 预估难度:普及-
  • 标签:枚举

题意

给定一个由大写英文字母组成的字符串 \(S\)
请统计 \(S\) 中有多少子串(连续子序列)满足以下两个条件:

  • 字符串的长度为奇数。
  • 字符串正中间的字符是 C

即使两个子串作为字符串是完全相同的,但只要它们来自原字符串的不同的位置,就可以被分别计数。

思路

由于 C 位于正中间,且字符串长度是奇数,说明字符 C 左右两侧的字符个数相同。

假设字符串下标在 \([0, n-1]\) 范围内,且此时有个字符 C 位于下标 \(p\) 位置,那么以这个 C 作为中点的字符串下标区间应当可以描述为 \([p-k, p+k]\),其中 \(k\) 满足:

  • \(k \ge 0\)
  • \(p-k \ge 0\),即 \(k \le p\)
  • \(p + k \lt n\),即 \(k \lt n - p\)

因此 \(k\) 的取值范围为 \(0 \le k \le \min(p, n-p-1)\),共 \(\min(p, n-p-1)+1\) 种。

于是我们便可以通过遍历来找出字符串中每一个字符 C 的下标位置,即可直接计算答案。

时间复杂度 \(O(|S|)\)

代码

void solve()
{string s;cin >> s;int n = s.size();long long ans = 0;for(int i = 0; i < n; i++)if(s[i] == 'C')ans += min(i, n - i - 1) + 1;cout << ans;
}

D - Chalkboard Median

  • 预估难度:普及/提高-
  • 标签:对顶堆

题意

黑板上写着一个整数 \(X\)

你需要按顺序处理 \(Q\) 次操作。第 \(i\) 次操作如下所示:

给定两个整数 \(A_i\)\(B_i\),将这两个新的整数写在黑板上。

然后,输出此时黑板上所有 \(2i+1\) 个整数的中位数。

思路

对顶堆数据结构模板题,具体可参考习题“中位数”。

我们可以假设目前的 \(2i+1\) 个整数已排序,并将排序后的数组分为左右两部分,左边包含 \(i\) 个数,右边包含 \(i+1\) 个数。

接下来使用一个大根堆,维护左边的 \(i\) 个数,堆顶朝右;再使用一个小根堆,维护右边的 \(i+1\) 个数,堆顶朝左。

于是我们便可以方便地借助这两个堆,将整个数组从中间“折断”,通过保证以下两个条件成立,来控制折断的位置一定在中位数旁:

  • 两个堆的大小差值不能超过 \(1\)
    • 要么两个堆具有相同数量的数字,要么控制右边的堆内数字数量比左边的堆多 \(1\)
  • 左边的大根堆内所有数字 \(\le\) 右边的小根堆内所有数字
    • 也就是控制让两个堆能够形象地维护一个有序数组。
    • 由于堆已自动排序,因此该条件也可以当作是让 左侧堆顶 \(\le\) 右侧堆顶

对于维护方法,由于每次会给定两个新数字,刚好可以给左边右边两个堆各一个,以保证上面的第一个条件成立。

接下来对于上面第二个条件,只要发现左侧堆顶 \(\gt\) 右侧堆顶,表示此时两个堆还没维护出一个有序数组,此时需要将两堆的堆顶进行交换,来让小的数字能到左半段去,大的数字到右半段去。

由于每次添加数字要么不会打乱数组的有序性,要么最多只会打乱一次,因此交换操作的执行次数最大只会在 \(O(Q)\) 的级别。

时间复杂度 \(O(Q\log Q)\)

代码

priority_queue<int> ql; // 左侧大根堆
priority_queue<int, vector<int>, greater<int>> qr; // 右侧小根堆void balance()
{while(ql.top() > qr.top()) // 如果左侧堆顶 > 右侧堆顶,则交换两堆顶{int a = ql.top();int b = qr.top();ql.pop();qr.pop();ql.push(b);qr.push(a);}
}void solve()
{int x;cin >> x;qr.push(x);int q;cin >> q;while(q--){cin >> x;ql.push(x);cin >> x;qr.push(x);// 左右两个堆各放一个,保持数量平衡balance(); // 通过交换两堆堆顶,使 左边堆内最大值 <= 右边堆内最小值cout << qr.top() << "\n";}
}

E - Count 123

  • 预估难度:普及+/提高
  • 标签:组合数学

题意

求满足以下条件的长度为 \(X_1+X_2+X_3\) 的序列 \(A = (a_1, \cdots, a_{X_1 + X_2 + X_3})\) 的数量。

  • \(A\) 中恰好包含 \(X_1\)\(1\)\(X_2\)\(2\),以及 \(X_3\)\(3\)
  • 相邻元素的差值绝对值至多为 \(1\)

结果对 \(998244353\) 取模。

思路

根据题意,相邻元素差值绝对值必须 \(\le 1\),换句话说就是数字 \(1\)\(3\) 不能相邻。那么数字 \(2\) 便成为了最特殊的数字,因为 \(2\) 与其它两种数字均可相邻。

于是我们可以选择把 \(2\) 当作挡板,先把所有 \(2\) 摆成一排,总共形成了 \(X_2+1\) 个空位(包括首尾)。

每个空位只能够填 \(1\) 或者 \(3\) 的其中一种数字,且一个空位里可以放多个相同的数字,当然也可以不放任何数字。

接下来,我们假设要从中选出 \(i\) 个空位专门放 \(1\),空位的选取方案数为 \(C_{X_2+1}^{i}\)。在选出这些空位后,需要将 \(X_1\)\(1\) 分成 \(i\) 份填入空位,这里可以采取隔板法,从 \(X_1-1\) 个空隙中选出 \(i-1\) 个放置隔板,填空方案数为 \(C_{X_1 - 1}^{i-1}\)

同理,在放完 \(1\) 后,可以假设在剩余的 \(X_2+1-i\) 个空位中再选 \(j\) 个空位专门放 \(3\),同上,空位选取方案数为 \(C_{X_2+1-i}^j\),填空方案数为 \(C_{X_3-1}^{j-1}\)

至此,序列方案总数可以通过 \(\displaystyle\sum_{i=1}^{X_2 + 1} \sum_{j=1}^{X_2+1-i} C_{X_2+1}^{i}C_{X_1 - 1}^{i-1}C_{X_2+1-i}^jC_{X_3-1}^{j-1}\) 求得。

考虑化简公式:

\[\begin{aligned} &\sum_{i=1}^{X_2 + 1} \sum_{j=1}^{X_2+1-i} C_{X_2+1}^{i} C_{X_1 - 1}^{i-1} C_{X_2+1-i}^j C_{X_3-1}^{j-1} \\ =&\sum_{i=1}^{X_2 + 1} C_{X_2+1}^{i} C_{X_1 - 1}^{i-1} \times (\sum_{j=1}^{X_2+1-i} C_{X_2+1-i}^j C_{X_3-1}^{j-1}) \end{aligned} \]


考虑内层公式。

\(A = X_2+1-i\)\(B = X_3 - 1\),那么内层公式可以看作:

\[\sum_{j=1}^{A} C_A^j C_B^{j-1} \]

根据组合数 \(C_n^m = C_n^{n-m}\)

\[=\sum_{j=1}^{A} C_A^{A-j} C_B^{j-1} \]

根据范德蒙德恒等式 \(\displaystyle\sum_{i=0}^k C_n^iC_m^{k-i} = C_{n+m}^k\)

\[=C_{A+B}^{A-1} = C_{X_2+X_3-i}^{X_2-i} \]


回到原式,则原式等于:

\[\begin{aligned} &\sum_{i=1}^{X_2 + 1} C_{X_2+1}^{i} C_{X_1 - 1}^{i-1} \times (\sum_{j=1}^{X_2+1-i} C_{X_2+1-i}^j C_{X_3-1}^{j-1}) \\ =& \sum_{i=1}^{X_2 + 1} C_{X_2+1}^{i} C_{X_1 - 1}^{i-1} C_{X_2+X_3-i}^{X_2-i} \end{aligned} \]

公式求解过程时间复杂度 \(O(|X_2|)\)

代码

typedef long long ll;ll fac[2000050];
ll inv[2000050];ll qpow(ll a, ll n)
{ll r = 1;while(n){if(n & 1)r = r * a % mod;a = a * a % mod;n >>= 1;}return r;
}void init()
{fac[0] = 1;for(int i = 1; i <= 2000000; i++)fac[i] = fac[i - 1] * i % mod;inv[2000000] = qpow(fac[2000000], mod - 2);for(int i = 1999999; i >= 0; i--)inv[i] = inv[i + 1] * (i + 1) % mod;
}ll getC(int n, int m)
{if(n - m < 0)return 0;return fac[n] * inv[m] % mod * inv[n - m] % mod;
}void solve()
{init();int X1, X2, X3;cin >> X1 >> X2 >> X3;long long ans = 0;for(int i = 1; i <= X2 + 1; i++){ans += getC(X2 + 1, i) * getC(X1 - 1, i - 1) % mod * getC(X2 + X3 - i, X2 - i) % mod;ans %= mod;}cout << ans;
}
http://www.jsqmd.com/news/830871/

相关文章:

  • 基于节点电价的电网对电动汽车接纳能力评估模型研究附Matlab代码
  • AI 不会只“犯错”:多智能体更可能“集体犯错”
  • STM32F4标准库工程模板升级指南:从V1.8.0固件库到168MHz主频的完整配置流程
  • 如何快速掌握开源视觉对比工具:MegSpot图片视频对比完整实战指南
  • 模型广场功能助力开发者根据场景与预算进行模型选型
  • 从MSDU到AMPDU:深入解析802.11ax前的帧聚合演进与实战权衡
  • 深度解析DockDoor:macOS窗口预览架构与效率提升机制
  • 桌面CNC双面PCB制作全流程:从设计到铣削的实战指南
  • WarcraftHelper:5大功能彻底解决魔兽争霸3在现代电脑上的兼容性问题
  • 配置 Claude Code 使用 TaoToken 作为稳定可靠的模型供应商
  • 告别手动开开关关!用这个C#小工具,让你的Praat语音标注效率翻倍
  • 别再手动查表了!用Fluent分子动理论自动算气体属性,附L-J参数查询指南
  • 15.郑州报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心
  • Reloaded-II模组加载器:为什么你的游戏模组总出问题?从依赖管理到稳定运行的完整指南
  • ARM架构TRCIDR寄存器详解与调试实践
  • 如何在Windows和Linux上免费运行macOS:VMware虚拟机终极解锁指南
  • CircuitPython实战:电容触摸与I2C传感器数据采集完整指南
  • 小团队福音:除了代码托管,Gitea内置的CI/CD、看板和Wiki功能怎么用?
  • 长沙氛围感写真推荐 | 2026本地拍照攻略:光影情绪的标配 - 麦克杰
  • WarcraftHelper:魔兽争霸3终极增强插件完整配置指南
  • 【参数估计】基于逐步积分和响应敏感性分析的分数阶混沌系统参数估计附matlab代码
  • ZYNQ7100实战:用AXI DMA搞定PL到PS的ADC数据流(Vivado 2017.4配置避坑)
  • 数字电路时序裕量保障:从RTL到物理实现的系统化工程实践
  • 基于Arduino FLORA的DIY智能手表:GPS导航与电子罗盘集成实践
  • 【实战】VOFM例程与条件表联用:构建动态采购定价引擎
  • SM2证书实战:从OpenSSL生成到Java代码解析与集成
  • Beyond Compare 5密钥生成全攻略:从激活失败到完全使用
  • 3分钟解锁Windows终极包管理器:winget-install一键部署实战指南
  • Python金融数据获取终极指南:3分钟快速掌握同花顺问财数据
  • 从通用到专业:剖析FinBERT如何通过领域预训练革新金融NLP