AtCoder Weekday Contest 0018 Beta题解(AWC 0018 Beta A-E)
A - Round-Trip Patrol
【题目来源】
AtCoder:A - Round-Trip Patrol
【题目描述】
Takahashi is a security guard who manages \(N\) checkpoints arranged in a straight line.
高桥是一名保安,负责管理 \(N\) 个排成一条直线的检查点。
The checkpoints are numbered \(1, 2, \ldots, N\) from left to right, and it takes exactly \(1\) second to move between adjacent checkpoints. Takahashi's station is at checkpoint \(N\).
检查点从左到右编号为 \(1, 2, …, N\),在相邻检查点之间移动恰好需要 \(1\) 秒。高桥的岗亭位于检查点 \(N\)。
When an anomaly detection alarm sounds, Takahashi departs from his station (checkpoint \(N\)) and travels through the checkpoints in the order \(N, N-1, \ldots, 1\) until he reaches checkpoint \(1\). He then turns around and travels through the checkpoints in the order \(1, 2, \ldots, N\), returning to his station (checkpoint \(N\)). The time required for inspection at each checkpoint and for turning around is \(0\) seconds. Therefore, the travel time for one patrol is \(2(N-1)\) seconds.
当异常检测警报响起时,高桥从他的岗亭(检查点 \(N\))出发,按顺序 \(N, N-1, …, 1\) 穿过检查点,直到到达检查点 \(1\)。然后他转身,按顺序 \(1, 2, …, N\) 穿过检查点,返回他的岗亭(检查点 \(N\))。在每个检查点的检查时间和转身时间均为 \(0\) 秒。因此,一次巡逻的旅行时间为 \(2(N-1)\) 秒。
Takahashi always returns to his station before departing for the next patrol. All \(M\) patrols follow the same route and take the same travel time.
高桥总是在出发进行下一次巡逻之前返回他的岗亭。所有 \(M\) 次巡逻都遵循相同的路线,并花费相同的旅行时间。
One day, the alarm sounded \(M\) times, and Takahashi performed \(M\) round-trip patrols. Find the total travel time (in seconds) for Takahashi's \(M\) patrols that day. Note that waiting time between patrols is not included.
一天,警报响起了 \(M\) 次,高桥执行了 \(M\) 次往返巡逻。求高桥当天 M 次巡逻的总旅行时间(以秒为单位)。注意,不包括巡逻之间的等待时间。
【输入】
\(N\) \(M\)
An integer \(N\) representing the number of checkpoints and an integer \(M\) representing the number of times the alarm sounded (the number of patrols) are given on a single line, separated by a space.
【输出】
Print the total time (in seconds) Takahashi spent traveling as an integer on a single line. Note that the answer can be as large as approximately \(2 \times 10^{18}\).
【输入样例】
3 1
【输出样例】
4
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, m; // n: 检查点数量
signed main()
{
cin >> n >> m; // m: 巡逻次数
// 计算并输出结果
cout << 2 * (n - 1) * m << endl;
return 0;
}
【运行结果】
3 1
4
B - Classroom Assignment
【题目来源】
AtCoder:B - Classroom Assignment
【题目描述】
Takahashi is organizing an event spanning \(N\) days at his school's cultural festival. The venue has \(M\) classrooms, and each classroom is scheduled to hold exactly one lecture per day. Classroom \(j\) (\(1 \leq j \leq M\)) has a capacity of \(C_j\) people.
高桥正在为学校的文化节组织一场为期 \(N\) 天的活动。会场有 \(M\) 间教室,每间教室每天恰好安排一场讲座。教室 \(j\)(\(1 ≤ j ≤ M\))可容纳 \(C_j\) 人。
On day \(i\) (\(1 \leq i \leq N\)), \(K_i\) visitors come to the cultural festival. Each visitor specifies exactly one classroom they wish to attend. Let \(P_{i,k}\) denote the classroom number desired by the \(k\)-th visitor (\(1 \leq k \leq K_i\)) on day \(i\). Note that multiple visitors may wish to attend the same classroom on the same day.
在第 \(i\) 天(\(1 ≤ i ≤ N\)),有 \(K_i\) 名参观者来到文化节。每名参观者恰好指定了一间他们希望参加的教室。令 \(P_{i,k}\) 表示第 \(i\) 天第 \(k\) 名参观者(\(1 ≤ k ≤ K_i\))期望的教室编号。注意,多名参观者可能希望在同一天参加同一间教室。
For each day, the following process is performed (the processing for each day is independent, and the result of one day does not affect another day). The number of applicants for each classroom on that day is tallied. If the number of applicants for a classroom is at most its capacity (i.e., number of applicants \(\leq\) capacity), then all applicants can attend that classroom's lecture. On the other hand, if the number of applicants exceeds the capacity (i.e., number of applicants \(>\) capacity), the lecture in that classroom is canceled for safety reasons, and none of the visitors who wished to attend that classroom can participate in any lecture. Furthermore, visitors whose desired classroom's lecture was canceled are not reassigned to other classrooms.
对于每一天,执行以下过程(每天的处理是独立的,且一天的结果不影响另一天)。统计当天每间教室的申请人数。如果某间教室的申请人数不超过其容量(即申请人数 ≤ 容量),则所有申请者都可以参加该教室的讲座。另一方面,如果申请人数超过容量(即申请人数 > 容量),则该教室的讲座出于安全原因被取消,且希望参加该教室的参观者都不能参加任何讲座。此外,期望教室的讲座被取消的参观者不会被重新分配到其他教室。
Determine the total number of visitors who actually attended a lecture across all \(N\) days of the event (the sum of the number of participants in each classroom on each day).
确定在整个活动的 \(N\) 天中,实际参加了讲座的参观者总数(即每天每间教室的参与者人数之和)。
【输入】
\(N\) \(M\)
\(C_1\) \(C_2\) \(\ldots\) \(C_M\)
\(K_1\)
\(P_{1,1}\) \(P_{1,2}\) \(\ldots\) \(P_{1,K_1}\)
\(K_2\)
\(P_{2,1}\) \(P_{2,2}\) \(\ldots\) \(P_{2,K_2}\)
\(\vdots\)
\(K_N\)
\(P_{N,1}\) \(P_{N,2}\) \(\ldots\) \(P_{N,K_N}\)
- The first line contains two space-separated integers: \(N\), the number of days of the event, and \(M\), the number of classrooms.
- The second line contains the space-separated integers \(C_1, C_2, \ldots, C_M\), representing the capacity of each classroom.
- The following \(2N\) lines provide the visitor information for each day. The information for day \(i\) consists of \(2\) lines:
- The first line contains an integer \(K_i\), the number of visitors on day \(i\).
- The second line contains the space-separated integers \(P_{i,1}, P_{i,2}, \ldots, P_{i,K_i}\), representing the classroom numbers desired by each of the \(K_i\) visitors.
【输出】
Output in a single line the total number of visitors who actually attended a lecture across all \(N\) days.
【输入样例】
2 3
3 2 4
5
1 2 1 2 2
3
1 3 3
【输出样例】
5
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100005;
int n, m, k, ans; // n: 操作次数,m: 颜色种类数,k: 当前操作的颜色数,ans: 总结果
int c[N]; // c[i]: 第i种颜色的限制数量
signed main()
{
cin >> n >> m; // 读入操作次数和颜色种类数
for (int i = 1; i <= m; i++)
{
cin >> c[i]; // 读入每种颜色的限制数量
}
for (int i = 1; i <= n; i++) // 处理每个操作
{
cin >> k; // 读入当前操作涉及的颜色数
map<int, int> mp; // 统计当前操作中每种颜色的出现次数
for (int j = 1; j <= k; j++)
{
int x;
cin >> x; // 读入颜色
mp[x]++; // 统计颜色出现次数
}
// 调试输出(被注释掉)
// for (int j=1; j<=m; j++)
// cout << p[j] << " ";
// cout << endl;
// 计算当前操作的有效数量
for (auto [color, cnt] : mp) // 遍历当前操作中的每种颜色
{
if (cnt <= c[color]) // 如果颜色数量不超过限制
{
ans += cnt; // 将数量加入总结果
}
}
}
cout << ans << endl; // 输出总结果
return 0;
}
【运行结果】
2 3
3 2 4
5
1 2 1 2 2
3
1 3 3
5
C - Bulk Character Conversion
【题目来源】
AtCoder:C - Bulk Character Conversion
【题目描述】
Takahashi is developing a text editor. This editor has a feature that performs bulk character replacement across multiple text files.
高桥正在开发一个文本编辑器。这个编辑器有一个功能,可以跨多个文本文件执行批量字符替换。
One day, Takahashi opened \(N\) text files. Each file contains a single line consisting of a string of lowercase English letters.
一天,高桥打开了 N 个文本文件。每个文件包含一行,由小写英文字母组成的字符串构成。
Takahashi will perform \(Q\) replacement operations on these files in order. In each operation, a specific character contained in all current files is replaced with another character all at once.
高桥将按顺序对这些文件执行 \(Q\) 次替换操作。在每次操作中,所有当前文件中包含的特定字符会一次性替换为另一个字符。
After all replacement operations are completed, output the string written in each file.
在所有替换操作完成后,输出每个文件中写入的字符串。
【输入】
\(N\) \(Q\)
\(S_1\)
\(S_2\)
:
\(S_N\)
\(a_1\) \(b_1\)
\(a_2\) \(b_2\)
:
\(a_Q\) \(b_Q\)
- The first line contains \(N\), the number of files, and \(Q\), the number of replacement operations, separated by a space.
- From the 2nd line to the \((N + 1)\)-th line, the strings written in each file are given.
- The \((1 + i)\)-th line contains the string \(S_i\) written in the \(i\)-th file.
- \(S_i\) consists only of lowercase English letters.
- From the \((N + 2)\)-th line to the \((N + Q + 1)\)-th line, the details of each replacement operation are given.
- The \((N + 1 + j)\)-th line contains the original character \(a_j\) to be replaced and the destination character \(b_j\) in the \(j\)-th operation, separated by a space.
- \(a_j\) and \(b_j\) are each a single lowercase English letter.
【输出】
\(T_1\)
\(T_2\)
:
\(T_N\)
- Output \(N\) lines, each containing the string in the corresponding file after all replacement operations are completed.
- The \(i\)-th line should contain the string \(T_i\) written in the \(i\)-th file.
【输入样例】
3 2
abc
dog
banana
a b
b c
【输出样例】
ccc
dog
ccncnc
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, q; // n: 字符串数量,q: 查询次数
string s[N]; // 存储所有字符串
int mp[130]; // 字符映射表,ASCII码范围0-127,足够覆盖'a'~'z'
int main()
{
cin >> n >> q; // 读入字符串数量和查询次数
for (int i = 1; i <= n; i++)
{
cin >> s[i]; // 读入每个字符串
}
// 初始化字符映射表,每个字符映射到自身
for (int i = 'a'; i <= 'z'; i++)
{
mp[i] = i;
}
while (q--) // 处理每个查询
{
char a, b;
cin >> a >> b; // 读入要替换的字符对
int x = a - 'a', y = b - 'a'; // 转换为0-25的索引(这行代码没有使用)
// 将所有映射到字符a的字符改为映射到字符b
for (int i = 'a'; i <= 'z'; i++)
{
if (mp[i] == a) // 如果字符i当前映射到字符a
{
mp[i] = b; // 将其改为映射到字符b
}
}
}
// 根据映射表替换所有字符串中的字符
for (int i = 1; i <= n; i++) // 遍历每个字符串
{
for (int j = 0; j < s[i].size(); j++) // 遍历字符串中的每个字符
{
s[i][j] = (char)mp[s[i][j]]; // 根据映射表替换字符
}
}
// 输出替换后的字符串
for (int i = 1; i <= n; i++)
{
cout << s[i] << endl;
}
return 0;
}
【运行结果】
3 2
abc
dog
banana
a b
b c
ccc
dog
ccncnc
D - Smart Shopper
【题目来源】
AtCoder:D - Smart Shopper
【题目描述】
Takahashi has come to a store with a budget of \(K\) yen.
高桥带着 \(K\) 日元的预算来到一家商店。
The store has \(N\) items on display, and the price of the \(i\)-th item is \(C_i\) yen. Takahashi can choose any items he likes from these items to purchase, but he can buy at most one of each item. He may also choose to buy nothing at all.
商店展示了 \(N\) 件商品,第 \(i\) 件商品的价格为 \(C_i\) 日元。高桥可以从这些商品中任意选择他喜欢的商品购买,但每种商品他最多只能买一件。他也可以选择什么都不买。
However, the total price of the purchased items must not exceed the budget of \(K\) yen.
但是,购买商品的总价格不得超过预算 \(K\) 日元。
Takahashi wants to maximize the total price of the purchased items while satisfying this condition.
高桥希望在满足此条件的前提下,最大化所购商品的总价格。
Among all ways to select items such that the total price is at most \(K\), find the maximum possible total price.
在所有选择商品且总价格不超过 \(K\) 的方式中,求可能的最大总价格。
【输入】
\(N\) \(K\)
\(C_1\) \(C_2\) \(\ldots\) \(C_N\)
- The first line contains an integer \(N\) representing the number of items and an integer \(K\) representing the budget, separated by a space.
- The second line contains integers \(C_1, C_2, \ldots, C_N\) representing the prices of the items, separated by spaces.
【输出】
Print in one line the maximum total price among all ways to select items such that the total price of the purchased items is at most \(K\).
【输入样例】
3 10
3 5 4
【输出样例】
9
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 105, M = 10005;
int n, k; // n: 物品数量,k: 背包容量
int c[N]; // c[i]: 第i个物品的价值(也是体积)
int dp[M]; // dp[j]: 容量为j时的最大价值
int main()
{
cin >> n >> k; // 读入物品数量和背包容量
for (int i = 1; i <= n; i++)
{
cin >> c[i]; // 读入每个物品的价值
}
// 0/1背包问题的动态规划
for (int i = 1; i <= n; i++) // 遍历每个物品
{
for (int j = k; j >= c[i]; j--) // 逆序遍历背包容量
{
// 状态转移方程:
// 不选第i个物品:dp[j] 保持不变
// 选第i个物品:dp[j - c[i]] + c[i]
// 取两者最大值
dp[j] = max(dp[j], dp[j - c[i]] + c[i]);
}
}
cout << dp[k] << endl; // 输出容量为k时的最大价值
return 0;
}
【运行结果】
3 10
3 5 4
9
E - Peak Collection
【题目来源】
AtCoder:E - Peak Collection
【题目描述】
Takahashi is trying to visit the summits of \(N\) mountains lined up in a row along a traverse route. The summits are numbered \(1, 2, \ldots, N\) from the entrance side of the route, and Takahashi starts from the entrance and proceeds one-way from lower-numbered to higher-numbered summits. He cannot return to a summit he has already passed.
高桥正试图沿着一条横贯路线,依次拜访 \(N\) 座排成一列的山峰的山顶。从路线入口侧开始,山顶编号为 \(1, 2, …, N\),高桥从入口出发,从编号较小的山峰单向前往编号较大的山峰。他不能返回已经经过的山顶。
Each summit \(i\) has an "entrance fee" of \(C_i\) yen and an "elevation" of \(S_i\). As Takahashi proceeds along the route, when he reaches each summit, he can choose either to climb it or to pass through without climbing. If he passes through without climbing, no entrance fee is charged. If he climbs it, he must pay that summit's entrance fee.
每座山峰 \(i\) 有"入场费" \(C_i\) 日元和"海拔" \(S_i\)。当高桥沿着路线前进,到达每座山峰时,他可以选择攀登它,或者不攀登而直接通过。如果他不攀登而直接通过,则不收取入场费。如果他攀登,则必须支付该山峰的入场费。
Takahashi has particular preferences for his mountaineering and wants to select which summits to climb such that all of the following conditions are satisfied:
高桥对登山有特别的偏好,他希望选择攀登哪些山顶,以满足以下所有条件:
- Upper limit on number of climbs: The number of summits climbed must be at most \(K\).
攀登次数上限:攀登的山顶数量不得超过 \(K\)。 - Strictly increasing elevation: When the climbed summits are listed in ascending order of their numbers, their elevations must be strictly increasing. That is, if he climbs summits \(i_1 < i_2 < \cdots < i_m\) in order, then \(S_{i_1} < S_{i_2} < \cdots < S_{i_m}\) must hold.
海拔严格递增:当按编号升序列出攀登的山顶时,它们的海拔必须严格递增。也就是说,如果他依次攀登山峰 \(i_1 < i_2 < ⋯ < i_m\),则必须满足 \(S_{i_1} < S_{i_2} < \cdots < S_{i_m}\)。 - Budget constraint: The total entrance fees of the climbed summits must not exceed his funds of \(B\) yen. That is, \(C_{i_1} + C_{i_2} + \cdots + C_{i_m} \leq B\) must hold.
预算约束:攀登的山顶的总入场费不得超过他的资金 \(B\) 日元。也就是说,必须满足 \(C_{i_1} + C_{i_2} + \cdots + C_{i_m} \leq B\)。
Takahashi wants to maximize the number of summits climbed \(m\) while satisfying all the above conditions. Find the maximum value of \(m\). Note that climbing no summits (\(m = 0\)) is also allowed.
高桥希望在满足上述所有条件的情况下,最大化攀登的山顶数量 \(m\)。求 \(m\) 的最大值。注意,不攀登山顶(\(m=0\))也是允许的。
【输入】
\(N\) \(K\) \(B\)
\(C_1\) \(S_1\)
\(C_2\) \(S_2\)
\(\vdots\)
\(C_N\) \(S_N\)
- The first line contains the number of summits \(N\), the upper limit on climbs \(K\), and the available funds \(B\), separated by spaces.
- In the following \(N\) lines, the \(i\)-th line (\(1 \leq i \leq N\)) contains the entrance fee \(C_i\) and elevation \(S_i\) of summit \(i\), separated by spaces.
【输出】
Print in one line the maximum number of summits \(m\) that can be climbed while satisfying all the conditions.
【输入样例】
5 3 10
3 100
2 200
5 150
4 300
1 400
【输出样例】
3
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int n, k, b; // n: 物品数量,k: 最大数量限制,b: 预算限制
int c[N], s[N]; // c[i]: 第i个物品的价格,s[i]: 第i个物品的属性值
int dp[N][N], ans; // dp[i][j]: 以第i个物品结尾,花费为j时的最大数量
int main()
{
cin >> n >> k >> b; // 读入物品数量、最大数量限制、预算限制
for (int i = 1; i <= n; i++)
{
cin >> c[i] >> s[i]; // 读入每个物品的价格和属性值
}
// 动态规划
for (int i = 1; i <= n; i++) // 遍历每个物品作为最后一个物品
{
if (c[i] <= b) // 如果当前物品价格不超过预算
{
dp[i][c[i]] = 1; // 只选择当前物品
}
for (int j = 0; j <= b; j++) // 遍历所有预算
{
for (int k = 1; k < i; k++) // 遍历之前的所有物品
{
if (s[k] < s[i] && j >= c[i]) // 如果属性值递增且预算足够
{
// 状态转移:从物品k转移到物品i
dp[i][j] = max(dp[i][j], dp[k][j - c[i]] + 1);
}
}
}
}
// 寻找满足条件的最大数量
for (int i = 1; i <= n; i++) // 遍历所有物品
{
for (int j = 0; j <= b; j++) // 遍历所有预算
{
if (dp[i][j] <= k) // 如果数量不超过限制k
{
ans = max(ans, dp[i][j]); // 更新答案
}
}
}
cout << ans << endl; // 输出结果
return 0;
}
【运行结果】
5 3 10
3 100
2 200
5 150
4 300
1 400
3
浙公网安备 33010602011771号