AtCoder Beginner Contest 442 ABCDEF 题目解析

news/2026/1/24 22:30:47/文章来源:https://www.cnblogs.com/stelayuri/p/19527700

A - Count .

  • 预估难度:入门
  • 标签:模拟

题意

给定一个由小写英文字母组成的字符串 \(S\),问 \(S\) 中有多少个字符为 i 或者 j

代码

void solve()
{string s;cin >> s;int cnt = 0;for(char c : s)if(c == 'i' || c == 'j')cnt++;cout << cnt;
}

B - Music Player

  • 预估难度:入门
  • 标签:模拟

题意

高桥有一个音乐播放器。最初,播放器的音量为 \(0\),且处于停止播放状态。

\(Q\) 个操作将依次进行。第 \(i\) 个操作以一个整数 \(A_i\) 表示,含义如下:

  • 如果 \(A_i = 1\),则音量增加 \(1\)
  • 如果 \(A_i = 2\),则音量减少 \(1\)。如果音量原本为 \(0\),则不做操作。
  • 如果 \(A_i = 3\),则改变播放状态。即如果当前处于播放状态,则改为停止播放状态;否则,改为播放状态。

在每次操作结束后,请判断播放器是否位于播放状态,且音量至少为 \(3\)

思路

简单模拟题,使用两个变量分别维护当前音量以及播放状态即可。

代码

void solve()
{int Q;cin >> Q;int volume = 0; // 音量bool playing = false; // 播放状态while(Q--){int a;cin >> a;if(a == 1)volume = volume + 1;else if(a == 2)volume = max(0, volume - 1);elseplaying = !playing;if(playing && volume >= 3)cout << "Yes\n";elsecout << "No\n";}
}

C - Peer Review

  • 预估难度:普及-
  • 标签:组合数学

题意

\(N\) 名研究员,编号分别为 \(1, 2, \ldots, N\)

在研究员之间存在着 \(M\) 个利益冲突。对于 \(i = 1, 2, \ldots, M\),已知研究员 \(A_i\)\(B_i\) 存在着利益冲突。

一篇论文的审稿人必须是三名不同的研究员,他们需要不同于论文作者,并且与论文作者之间没有利益冲突。

我们假设每篇论文都只有一位作者。

对于 \(i = 1, 2, \ldots, N\),试求出有多少组不同的研究员三元组,能够作为研究员 \(i\) 所撰写的论文的审稿人?

思路

根据数据范围,保证不存在重复的利益冲突关系。于是我们可以借助计数数组 \(\text{cnt}[i]\) 统计有多少人与研究员 \(i\) 存在利益冲突。

最后对于第 \(i\) 名研究员,除去自己以外,有 \((n-1)-\text{cnt}[i]\) 人是与其没有冲突的。我们可以从这些人中任选三人作为其论文的审稿人。

\(t = (n-1)-\text{cnt}[i]\),则方案总数为从 \(t\) 人中任选三人的组合方案数量,为 \(\text{C}_{t}^3=\frac{t(t-1)(t-2)}{6}\)

代码

int n, m, cnt[200005];
// cnt[i] 表示有多少人与 i 存在冲突void solve()
{cin >> n >> m;for(int i = 1; i <= m; i++){int a, b;cin >> a >> b;cnt[a]++;cnt[b]++;}for(int i = 1; i <= n; i++){int t = n - 1 - cnt[i];// 共 t 人与 i 无冲突,从中选出三人,求组合方案cout << 1LL * t * (t - 1) * (t - 2) / 6 << " ";}
}

D - Swap and Range Sum

  • 预估难度:普及-
  • 标签:前缀和 / 数据结构

题意

给定一个长度为 \(N\) 的序列 \(A=(A_1,A_2,\dots,A_N)\)

请按顺序处理 \(Q\) 个询问。每个询问的格式如下:

  • 1 x :交换 \(A_x\)\(A_{x+1}\) 的值。
  • 2 l r:查找 \(\displaystyle \sum_{l\leq i\leq r} A_i\) 的值。

思路

题目涉及区间求和操作,一般来说静态区间可以直接采用前缀和,而如果涉及修改,则需要借助树状数组/线段树等数据结构进行维护。

考虑本题的修改操作,发现每次只会交换序列中的两个数,并且这两个数在原序列中是相邻的

假设 \(S\)\(A\) 序列的前缀和序列,其中 \(S_i = \sum\limits_{j=1}^i A_j\)

  • 由于只会交换,因此整个序列的总和 \(S_N\) 是不变的。
  • 又因为发生交换的是相邻两个数字 \(A_x\)\(A_{x+1}\),明显 \(x-1\) 及之前的所有位置的前缀和,以及 \(x+1\) 及之后的所有位置的前缀和均不会发生更改,因此只需要更新 \(x\) 这一个位置的前缀和数组即可。

综上,借助前缀和可以在 \(O(N+Q)\) 的时间复杂度内完成所有任务(代码一)。

或者直接借助高级数据结构在 \(O(N+Q\log N)\) 的时间复杂度内完成(代码二)。

代码一

int a[200005], s[200005];void solve()
{int n, q;cin >> n >> q;for(int i = 1; i <= n; i++){cin >> a[i];s[i] = s[i - 1] + a[i];}while(q--){int op;cin >> op;if(op == 1){int x;cin >> x;swap(a[x], a[x+1]);s[x] = s[x-1] + a[x]; // 仅更新 x 位置的前缀和即可}else{int l, r;cin >> l >> r;cout << s[r] - s[l-1] << "\n";}}
}

代码二

struct BIT
{int n, a[200005];void init(int _n){n = _n;for(int i = 0; i <= n; i++)a[i] = 0;}void update(int p, int v){while(p <= n){a[p] += v;p += p & -p;}}int query(int p){int r = 0;while(p){r += a[p];p -= p & -p;}return r;}
};BIT tree;
int a[200005];void solve()
{int n, q;cin >> n >> q;tree.init(n);for(int i = 1; i <= n; i++){cin >> a[i];tree.update(i, a[i]);}while(q--){int op;cin >> op;if(op == 1){int x;cin >> x;tree.update(x, a[x+1] - a[x]);tree.update(x+1, a[x] - a[x+1]);swap(a[x], a[x+1]);}else{int l, r;cin >> l >> r;cout << tree.query(r) - tree.query(l-1) << "\n";}}
}

E - Laser Takahashi

  • 预估难度:普及+/提高 (知识点位于 省选
  • 标签:计算几何、排序

题意

在一个二维平面上有 \(N\) 只怪物。怪物分别编号为 \(1, 2, \dots, N\),且怪物 \(i\) 所在的坐标为 \((X_i, Y_i)\),保证 \((X_i,Y_i) \neq (0,0)\) 。(每个怪物都可以视为一个静止的点。也就是说,怪物没有大小之分)。

高桥站在这个平面的原点处,他的双眼总是能发射出强大的激光(可以当作是一条从原点出发的射线),并瞬间消灭他所面向的所有怪物(若多只怪物与原点共线,则全部消灭)。

青木正在进行 \(Q\)独立的思想实验。第 \(j\) 次思想实验如下:

  • 最初,高桥面向怪物 \(A_j\) 所在的方向。从现在起,高桥将按顺时针方向一直旋转,直到他朝向怪物 \(B_j\) 所在的方向时才会停止旋转。问在这个旋转过程中,他一共会消灭多少只怪兽(包括怪物 \(A_j\)\(B_j\))?
    • 如果怪物 \(A_j\)\(B_j\) 在同一方向上,那么高桥就不会旋转。

思路

一道比较模板的极角排序题。先按顺时针将所有点进行排序,与原点共线时可以任意处理。

  • 为规避浮点数带来的精度误差问题,极角排序最好采用向量叉积判符号的形式进行处理。先判断两点是否同时在坐标系的上半部分(第一、第二象限)或下半部分(第三、第四象限),如果不是,则优先让上半部分的点排在前。若两点同时位于某半部分,则按照原点出发的向量叉积正负性排序,顺时针则判断叉积 \(\lt 0\) 即可。

排序完成之后,如果保证不存在任意两点与原点能够组成三点共线的情况的话,我们便可以根据输入的起点 \(a\) 与终点 \(b\) 的编号,通过一个映射数组 pos[] 在排序后的序列中快速找出其对应的新下标。

\(p = \text{pos}[a], q = \text{pos}[b]\)

  • 如果 \(p \le q\),则能杀死的怪物就是新序列中下标在 \([p, q]\) 区间内的所有怪物,数量为 \(q - p + 1\)
  • 如果 \(p \gt q\),则能杀死的怪物就是新序列中下标在 \([p, N]\)\([1, q]\) 区间内的所有怪物,数量为 \(N-p+1+q\)

但本题可能出现多只怪物与原点共线的情况,需要特殊处理。在排序后的序列中,由于方向相同的点一定是连续出现的,因此可以借助循环来对于每个点快速求出与我方向相同的所有点的最小下标及最大下标,分别记作 L[i]R[i]

  • 判断两个向量的方向是否相同,首先向量叉积需要 \(=0\),但这只能保证两向量共线,可能会出现方向相反的情况。所以最好再套上一个点积 \(\gt 0\) 的判断,以保证两向量夹角不超过 \(90^{\circ}\)

然后记 \(p = \text{L}[\text{pos}[a]], q = \text{R}[\text{pos}[b]]\),再进行上述的分类讨论即可。

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

代码

typedef long long ll;struct Point
{ll x, y;int id;Point(){}Point(ll x, ll y): x(x), y(y){}
};ll Dot(Point a, Point b) // 向量点积
{return a.x * b.x + a.y * b.y;
}
ll Cross(Point a, Point b) // 向量叉积
{return a.x * b.y - a.y * b.x;
}bool cmp(Point &a, Point &b)
{// 弧度 [-PI, 0) 作为下方两象限,[0, +PI) 作为上方两象限bool fa = a.y > 0 || a.y == 0 && a.x > 0; // 判断 a 在不在坐标系的上半部分bool fb = b.y > 0 || b.y == 0 && b.x > 0;if(fa != fb) // 两点不同时在坐标系的上半/下半部分return fa; // 将上半部分的点排在前面return Cross(a, b) < 0; // 两点同时在上方/下方的象限内,直接按叉积顺时针排序
}int n, q;
Point p[200005];int pos[200005];
// pos[i] 表示原本第 i 个点在排序后的数组中的哪个下标int L[200005], R[200005];
// L[i], R[i] 表示与排序后的第 i 个点方向相同的所有点的最小及最大下标void solve()
{cin >> n >> q;for(int i = 1; i <= n; i++){cin >> p[i].x >> p[i].y;p[i].id = i;}sort(p + 1, p + n + 1, cmp);for(int i = 1; i <= n; i++)pos[p[i].id] = i;L[1] = 1;for(int i = 2; i <= n; i++){if(Cross(p[i-1], p[i]) == 0 && Dot(p[i-1], p[i]) > 0) // 两点在同个方向上,继承上个点的最小下标L[i] = L[i-1];elseL[i] = i;}R[n] = n;for(int i = n-1; i >= 1; i--){if(Cross(p[i+1], p[i]) == 0 && Dot(p[i+1], p[i]) > 0) // 两点在同个方向上,继承下个点的最小下标R[i] = R[i+1];elseR[i] = i;}while(q--){int a, b;cin >> a >> b;a = L[pos[a]];b = R[pos[b]];if(a <= b)cout << (b - a + 1) << "\n";elsecout << (n - a + 1) + b << "\n";}
}

F - Diagonal Separation 2

  • 预估难度:普及+/提高
  • 标签:动态规划、前缀和

题意

有一个 \(N\)\(N\) 列的网格图。第 \(i\) 行第 \(j\) 列的位置被称作 \((i, j)\)

图中的每个网格都会被涂成白色或黑色。网格的初始涂色信息由 \(N\) 个字符串 \(S_1, S_2, \ldots, S_N\) 给出:

  • 如果字符串 \(S_i\) 的第 \(j\) 个字符是 .,则网格 \((i, j)\) 会被涂成白色;
  • 如果字符串 \(S_i\) 的第 \(j\) 个字符是 #,则网格 \((i, j)\) 会被涂成黑色。

您将重新绘制一些网格的颜色,以同时满足以下两个条件:

  • 对于每一行:所有白色网格全部集中在该行的左侧,所有黑色网格全部集中在该行的右侧。
  • 对于每一列:所有白色网格全部集中在该列的上方,所有黑色网格全部集中在该列的下方。

求为了满足条件所需要重新涂色的网格数量最小值。

思路

根据题意,每一行的黑色格子必须连续集中在右侧,每一列的黑色格子必须连续集中在下方,可知对于网格图中的每一个黑色格子,其右下方必定也全都是黑色格子。

换句话说,如果第 \(i\) 行最靠左的黑色格子位于第 \(j\) 列,那么第 \(i+1\) 行最靠左的黑色格子的列数一定 \(\le j\)

相邻两行之间黑色格子的起始列存在限制关系,考虑动态规划。

\(\text{dp}[i][j]\) 表示从上往下考虑到第 \(i\) 行,并且第 \(i\) 行最靠左的黑色格子位于第 \(j\) 列时,需要重新涂色的网格数量最小值是多少。如果该行不存在黑色格子(全白),则令 \(j=N+1\)

根据上面的讨论,可以简单地得到状态转移方程为:

\[\text{dp}[i][j] = \min_{k=j}^{N+1}(\text{dp}[i-1][k]) + \text{让第 }i\text{ 行黑色格子从第 }j\text{ 列开始需要改变的网格数} \]

先考虑让第 \(i\) 行的黑色格子改成从第 \(j\) 列开始,所需要改变的网格数量。明显此时这一行第 \(1 \sim j-1\) 列上的所有黑色格子都得改成白色格子,第 \(j \sim N\) 列上的所有白色格子都得改成黑色格子,这两部分数量均可以借助行上的一维前缀和或是整体的二维前缀和来快速求出。

但即使这一数量能快速求出,上述状态转移方程仍是 \(O(N^3)\) 的。考虑 \(\min\limits_{k=j}^{N+1}(\text{dp}[i-1][k])\) 这一项求解的优化。我们只需要将状态中的第二维 \(j\) 倒序进行求解,这样就可以在枚举 \(j\) 的同时,用一个变量辅助维护上一行第 \(j\) 列的后缀最小值了。

最终时间复杂度 \(O(N^2)\)

代码

int n;
int a[5005][5005];
// a[i][j] = 0/1 表示 白/黑
int s[5005][5005];
// s[i] 为 a[i] 这一行的 黑色格子数量 的一维前缀和
int dp[5005][5005];
// dp[i][j] 表示从上往下看到第 i 行
// 且第 i 行最靠左的黑色格子位于第 j 列时
// 需要改变的格子数量最小值void solve()
{cin >> n;for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++){char c;cin >> c;if(c == '#')a[i][j] = 1;s[i][j] = s[i][j-1] + a[i][j];}for(int i = 1; i <= n; i++){int minn = dp[i-1][n+1]; // 维护 dp[i-1][j后面的所有列] 中的 最小值for(int j = n+1; j >= 1; j--) // 倒序枚举当前这一行最左侧黑色格子的位置{// 1 ~ j-1 的黑色全改白色,j ~ n 的白色全改黑色int t = s[i][j-1] + ((n-j+1) - (s[i][n] - s[i][j-1]));// 将上一行 j 列的答案纳入 minn,更新后缀最小值minn = min(minn, dp[i-1][j]);// 上一行黑色格子起始列 >= j 的最小答案,加上当前行黑色格子以 j 作为起始列的操作数dp[i][j] = minn + t;}}int ans = 1e9;for(int j = 1; j <= n+1; j++)ans = min(ans, dp[n][j]);cout << ans;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1211366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何选择合适的二维码,静态码和活码各有何优势?

在选择二维码时&#xff0c;理解静态码和活码的特点非常重要。静态二维码提供了一种简单直接的解决方案&#xff0c;适合不需要变化的内容&#xff0c;例如支付或基本的信息共享。而活码则更为灵活&#xff0c;可以随时更新信息&#xff0c;这使其在持续推广或活动管理中非常有…

洛谷 P1651 塔 题解

题目链接 洛谷 P1651 塔 思路分析 Task 1 考虑动态规划。我们定义 \(dp_{j,k}\) 表示当一塔高度为 \(j\),另一塔高度为 \(k\) 能否搭出。那么 \(dp_{j,k}=dp_{j,k}\lor dp_{j-a_i,k}\lor dp_{k,j-a_i}\),其中 \(i\) …

热销榜单:2026年在线制作二维码推荐,帮你轻松打造个性化二维码!

在当前的数字时代&#xff0c;在线制作二维码工具越来越受到重视。无论是个人还是企业&#xff0c;都希望能够快速、方便地生成二维码&#xff0c;用于信息分享和活动管理。通过在线工具&#xff0c;用户可以轻松将图文、音视频或文档转化为二维码。各大平台提供的这些工具&…

vllm Qwen2.5-0.5B输出乱码解决办法 用-Instruct版本的

我重新下过了&#xff0c;也改变量了&#xff0c;bfloat16改float16都没好重新下-Instruct就行了

二维码在图片传播中的重要性是什么?

二维码在图片传播中极大提升了信息传递的效率。用户可以直接通过扫描二维码&#xff0c;快速获取产品信息、活动详情等&#xff0c;省去手动输入的繁琐。这种方式提升了用户体验&#xff0c;使得信息获取变得方便快捷。设计上&#xff0c;巧妙地将二维码融入产品图片或宣传图&a…

从零学网络安全 - 网络安全基础(二)

前情回顾协议 一句话口诀 核心作用IP 地址 设备的 “网络门牌号” 跨网段定位设备位置MAC 地址 网卡的 “身份证” 局域网内唯一标识设备ARP 协议 IP 转 MAC 的 “翻译官” 解决同一网段内 IP 与 MAC 的映射问题ICMP 协…

导师推荐10个AI论文平台,研究生高效写作必备!

导师推荐10个AI论文平台&#xff0c;研究生高效写作必备&#xff01; AI工具如何助力论文写作&#xff0c;让科研更高效 在当前学术研究日益数字化的背景下&#xff0c;AI工具已经成为研究生和科研工作者不可或缺的助手。尤其是在论文写作过程中&#xff0c;AI不仅能够提升效率…

让 uv 直接使用 conda 的环境

在 python 开发的时候有时候可能需要 conda 来安装一些 C++ 的库。一般来说,我个人就简单使用 conda + pip 了。但这次,我希望同时借助 uv 来实现现代化的项目管理。本来是考虑 pixi 的,但是国内还是没有完整的 pix…

人群仿真软件:SimWalk_(9).结果分析与可视化

结果分析与可视化 在人群仿真软件中&#xff0c;结果分析与可视化是极为重要的环节。通过这一环节&#xff0c;我们可以直观地理解仿真过程中的各种数据和现象&#xff0c;从而对仿真模型进行优化和改进。本节将详细介绍如何在人群仿真软件中进行结果分析与可视化&#xff0c;…

人群仿真软件:SimWalk_(10).案例学习与应用

案例学习与应用 在这一部分&#xff0c;我们将通过实际案例学习如何在人群仿真软件SimWalk中进行二次开发。我们将探讨不同的应用场景&#xff0c;从简单的脚本编写到复杂的自定义模块开发&#xff0c;帮助您更好地理解和掌握SimWalk的开发技术。每个案例都包含详细的原理说明…

人群仿真软件:SimWalk_(10).人群应急疏散仿真

人群应急疏散仿真 1. 概述 在人群仿真软件中&#xff0c;应急疏散仿真是一个重要的应用领域。它主要用于模拟在紧急情况下人群的疏散行为&#xff0c;帮助评估和优化公共设施、建筑、交通系统等的安全性和疏散效率。本节将详细介绍如何在SimWalk中进行人群应急疏散仿真的设置…

人群仿真软件:SimWalk_(11).高级功能探索

高级功能探索 在前面的章节中&#xff0c;我们已经介绍了人群仿真软件的基本功能和使用方法。本章将深入探讨一些高级功能&#xff0c;这些功能可以帮助用户进一步优化仿真模型&#xff0c;提高仿真结果的准确性和实用性。我们将重点介绍如何通过二次开发来实现这些高级功能&am…

【MIMO通信】大规模多元MIMO系统中的低复杂混合预编码附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

【无人机三维路径规划】基于人工势场路径规划算法实现无人机UAV和自主水下航行器AUV路径规划附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

从零开始学AI产品经理:4大方向选择+薪资分析+转型建议,建议收藏

简介 文章介绍了AI产品经理的四大分类维度&#xff08;按技术栈分层、业务领域、技术方向&#xff09;&#xff0c;详细分析了不同类型AI产品经理的薪资对比和发展前景&#xff0c;提供了基于个人背景、兴趣和行业趋势的方向选择建议。预测了2025年重点发展方向&#xff0c;为…

AI产品经理与传统产品经理的区别,大模型时代产品经理进阶指南

本文详细对比了AI产品经理与传统产品经理在职责范围、工作重心、技术要求和工作内容等方面的差异。AI产品经理需具备更多技术知识&#xff0c;主要负责解决效率问题&#xff0c;面向企业服务&#xff0c;工作重点包括Prompt工程、模型选型等。文章还提供了成为AI产品经理的建议…

Golang WebSocket的多客户端管理

Golang WebSocket的多客户端管理&#xff1a;从「单向快递」到「双向调度中心」关键词&#xff1a;Golang、WebSocket、多客户端管理、实时通信、连接池、消息广播、会话管理摘要&#xff1a;WebSocket是互联网时代的「双向对讲机」&#xff0c;让服务器和客户端能实时「聊个不…

2026年的第一篇

还好吧,是吧变化挺大 1.基本决定放弃OI,转数竞,这个寒假可能要自学一下 2.期末还有一个周,压力貌似不算很大 有时候我会让deepseek给我写点小说看,都是以我自己为原型 我发现我比小说中的我厉害太多了 我可以接受…

提升开题报告质量:9款人工智能工具与专业模板修改技巧分享

工具对比速览 工具名称 核心功能 适用场景 效率评分 特色优势 AIBiYe 开题报告生成/降重 中文论文全流程 ★★★★★ 国内院校适配度高 AICheck 初稿生成/格式检查 快速产出框架 ★★★★☆ 结构化输出优秀 AskPaper 文献综述辅助 外文文献处理 ★★★★ 跨…

9种AI驱动的高效工具组合,助力毕业论文开题报告模板修改

工具对比速览 工具名称 核心功能 适用场景 效率评分 特色优势 AIBiYe 开题报告生成/降重 中文论文全流程 ★★★★★ 国内院校适配度高 AICheck 初稿生成/格式检查 快速产出框架 ★★★★☆ 结构化输出优秀 AskPaper 文献综述辅助 外文文献处理 ★★★★ 跨…