AtCoder Weekday Contest 0005 Beta题解(AWC 0005 Beta A-E)
A - Reward of Multiples
【题目来源】
AtCoder:A - Reward of Multiples
【题目描述】
Takahashi is in charge of accounting at his company and is managing this month's bonus payments to employees.
高桥负责公司的会计工作,正在管理本月给员工的奖金发放。
The company has \(N\) employees, and each employee has a compensation amount determined by their performance. The compensation amount for the \(i\)-th employee is \(P_i\) yen.
公司有 \(N\) 名员工,每位员工的奖金金额根据其绩效确定。第 \(i\) 名员工的奖金金额为 \(P_i\) 日元。
The company president gave the following instruction: "I would like to give a special allowance to employees whose compensation amount is a multiple of \(K\). First, please tell me the total of the compensation amounts for the applicable employees."
公司总裁给出了以下指示:"我希望向奖金金额是 \(K\) 的倍数的员工发放特殊津贴。首先,请告诉我符合条件员工的奖金金额总和。"
Help Takahashi find the total of the compensation amounts for employees whose compensation amount is a multiple of \(K\) (that is, \(P_i\) is divisible by \(K\)). If there are no such employees, the total is \(0\).
帮助高桥计算奖金金额是 \(K\) 的倍数(即 \(P_i\) 能被 \(K\) 整除)的员工奖金金额总和。如果不存在这样的员工,总和为 \(0\)。
【输入】
\(N\) \(K\)
\(P_1\) \(P_2\) \(\ldots\) \(P_N\)
- The first line contains an integer \(N\) representing the number of employees and an integer \(K\) used for the divisibility check, separated by a space.
- The second line contains \(N\) integers \(P_1, P_2, \ldots, P_N\) representing the compensation amounts of each employee, separated by spaces.
【输出】
Print the total of the compensation amounts for employees whose compensation amount is a multiple of \(K\), on a single line.
【输入样例】
5 3
6 7 9 12 5
【输出样例】
27
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, k, ans; // n: 数据个数,k: 除数,ans: 总和
signed main()
{
cin >> n >> k; // 读入数据个数和除数
for (int i = 1; i <= n; i++)
{
int x;
cin >> x; // 读入当前数字
if (x % k == 0) // 如果当前数字能被k整除
{
ans += x; // 累加到总和中
}
}
cout << ans << endl; // 输出总和
return 0;
}
【运行结果】
5 3
6 7 9 12 5
28
B - Updating the Report Card
【题目来源】
AtCoder:B - Updating the Report Card
【题目描述】
Takahashi is managing student grades as the homeroom teacher of a school class. There are \(N\) students in the class, numbered from \(1\) to \(N\). The initial score of the \(i\)-th student is \(S_i\) points.
高桥担任学校班级的班主任,负责管理学生成绩。班级中共有 \(N\) 名学生,编号从 \(1\) 到 \(N\)。第 \(i\) 名学生的初始分数为 \(S_i\) 分。
At the end of the term, it is time to update the report cards. A total of \(M\) updates are performed. In the \(j\)-th update, the score of student \(P_j\) is changed to \(V_j\) points. The same student may be updated multiple times, in which case their score is overwritten with each update.
学期末,到了更新成绩单的时候。总共执行 \(M\) 次更新。在第 \(j\) 次更新中,学生 \(P_j\) 的分数被改为 \(V_j\) 分。同一名学生可能被多次更新,这种情况下,每次更新都会覆盖其之前的分数。
After all updates are completed, students with a score strictly less than \(K\) points are required to attend supplementary lessons. For Takahashi's sake, determine the number of students who are required to attend supplementary lessons. Note that students with exactly \(K\) points are not included.
所有更新完成后,分数严格小于 \(K\) 分的学生需要参加补习课程。为帮助高桥,请确定需要参加补习课程的学生人数。注意,分数恰好为 \(K\) 分的学生不包含在内。
【输入】
\(N\) \(M\) \(K\)
\(S_1\) \(S_2\) \(\cdots\) \(S_N\)
\(P_1\) \(V_1\)
\(P_2\) \(V_2\)
\(\vdots\)
\(P_M\) \(V_M\)
- The first line contains \(N\) representing the number of students, \(M\) representing the number of updates, and \(K\) representing the threshold score for supplementary lessons, separated by spaces.
- The second line contains the initial scores \(S_1, S_2, \ldots, S_N\) of each student, separated by spaces.
- \(S_i\) represents the initial score of the \(i\)-th student.
- Lines \(3\) through \(2 + M\) contain the details of the updates (if \(M = 0\), this part does not exist).
- Line \(2 + j\) contains the student number \(P_j\) whose score is changed in the \(j\)-th update and the new score \(V_j\), separated by a space.
【输出】
After all updates are completed, output in a single line the number of students whose score is strictly less than \(K\) points and are therefore required to attend supplementary lessons.
【输入样例】
5 3 60
45 72 58 81 39
1 65
3 62
5 55
【输出样例】
1
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, m, k, ans; // n: 学生数量,m: 操作次数,k: 分数线,ans: 不达标人数
int s[N]; // 学生分数数组
int main()
{
cin >> n >> m >> k; // 读入学生数量、操作次数、分数线
for (int i = 1; i <= n; i++)
{
cin >> s[i]; // 读入学生初始分数
}
for (int i = 1; i <= m; i++)
{
int p, v; // p: 学生编号,v: 新分数
cin >> p >> v; // 读入修改操作
s[p] = v; // 更新学生分数
}
for (int i = 1; i <= n; i++)
{
if (s[i] < k) // 如果学生分数低于分数线
{
ans++; // 计数加1
}
}
cout << ans << endl; // 输出不达标人数
return 0;
}
【运行结果】
5 3 60
45 72 58 81 39
1 65
3 62
5 55
1
C - Staircase-Shaped Flower Bed
【题目来源】
AtCoder:C - Staircase-Shaped Flower Bed
【题目描述】
Takahashi works as a gardener and is in charge of maintaining a row of flower beds.
高桥是一名园丁,负责维护一排花坛。
There are \(N\) flower beds, each numbered from \(1\) to \(N\). Each flower bed \(i\) (\(1 \leq i \leq N\)) currently has \(A_i\) flowers planted in it.
有 \(N\) 个花坛,每个编号从 \(1\) 到 \(N\)。每个花坛 \(i\)(\(1 ≤ i ≤ N\))目前种植了 \(A_i\) 株花。
According to Takahashi's boss, the condition for the row of flower beds to be in a beautiful state is that "for all adjacent flower beds, the absolute difference in the number of flowers is at most \(K\)." In other words, if we denote the number of flowers in each flower bed \(i\) after maintenance as \(B_i\), then the row of flower beds is considered beautiful when \(|B_i - B_{i+1}| \leq K\) holds for all \(i\) (\(1 \leq i \leq N - 1\)).
根据高桥的老板要求,这排花坛处于美丽状态的条件是"对于所有相邻的花坛,花的株数之差的绝对值至多为 \(K\)。" 换言之,如果我们用 \(B_i\) 表示维护后每个花坛 \(i\) 中的花株数,那么当对于所有 \(i\)(\(1 ≤ i ≤ N-1\))都满足 \(|B_i - B_{i+1}| ≤ K\) 时,这排花坛被认为是美丽的。
Takahashi can plant new flowers but cannot remove flowers that are already planted. Specifically, for each flower bed \(i\), he can add \(0\) or more flowers to increase the number of flowers from \(A_i\) to \(B_i\). Here, each \(B_i\) must be an integer satisfying \(B_i \geq A_i\).
高桥可以种植新的花,但不能移除已种植的花。具体而言,对于每个花坛 \(i\),他可以添加 \(0\) 株或更多花,将花株数从 \(A_i\) 增加到 \(B_i\)。此处,每个 \(B_i\) 必须是满足 \(B_i ≥ A_i\) 的整数。
Takahashi wants to minimize the total number of flowers added \(\displaystyle\sum_{i=1}^{N} (B_i - A_i)\) in order to make the row of flower beds beautiful. Find this minimum value.
高桥希望最小化为了使这排花坛变得美丽而添加的花朵总数 \(\displaystyle\)\(\displaystyle\sum_{i=1}^{N} (B_i - A_i)\)。求这个最小值。
Note that it is always possible to achieve a beautiful state by only adding flowers, since the condition can be satisfied by setting all \(B_i\) to the same sufficiently large value.
注意,通过仅添加花朵总是可以达到美丽状态,因为通过将所有 \(B_i\) 设置为相同且足够大的值可以满足条件。
【输入】
\(N\) \(K\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)
- The first line contains an integer \(N\) representing the number of flower beds and an integer \(K\) representing the allowed difference in the number of flowers between adjacent flower beds, separated by a space.
- The second line contains integers \(A_1, A_2, \ldots, A_N\) representing the number of flowers currently planted in each flower bed \(i\), separated by spaces.
【输出】
Output in one line the minimum total number of flowers that need to be added to make the row of flower beds beautiful.
【输入样例】
3 2
1 5 3
【输出样例】
2
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, k, ans; // n: 元素个数,k: 相邻元素最大差值,ans: 总增量
int a[N], b[N], l[N], r[N]; // a: 原数组,b: 调整后数组,l/r: 左右约束数组
signed main()
{
cin >> n >> k; // 读入n和k
for (int i = 1; i <= n; i++)
{
cin >> a[i]; // 读入原数组
}
// 从左向右计算约束
l[1] = a[1]; // 第一个元素的左约束就是它本身
for (int i = 2; i <= n; i++)
{
// 当前元素的左约束 = max(当前值, 前一个左约束 - k)
l[i] = max(a[i], l[i - 1] - k);
}
// 从右向左计算约束
r[n] = a[n]; // 最后一个元素的右约束就是它本身
for (int i = n - 1; i >= 1; i--)
{
// 当前元素的右约束 = max(当前值, 后一个右约束 - k)
r[i] = max(a[i], r[i + 1] - k);
}
// 计算最终调整后的值和总增量
for (int i = 1; i <= n; i++)
{
b[i] = max(l[i], r[i]); // 取左右约束中的最大值
ans += b[i] - a[i]; // 累加调整的增量
}
cout << ans << endl; // 输出总增量
return 0;
}
【运行结果】
3 2
1 5 3
2
D - Splitting Delivery Packages
【题目来源】
AtCoder:D - Splitting Delivery Packages
【题目描述】
Takahashi is in charge of delivery planning at a shipping company.
高桥负责一家货运公司的送货路线规划工作。
Today, he needs to create a plan to deliver \(N\) packages using \(K\) trucks.
今天,他需要制定一个使用 \(K\) 辆卡车运送 \(N\) 个包裹的计划。
Each package is numbered from \(1\) to \(N\), and the weight of package \(i\) is \(A_i\).
每个包裹编号从 \(1\) 到 \(N\),且包裹 \(i\) 的重量为 \(A_i\)。
To improve delivery efficiency, he decided to arrange the packages \(1, 2, \ldots, N\) in this order and divide them into \(K\) contiguous segments, each containing at least \(1\) package, and assign the packages in each segment to one truck. Every package belongs to exactly one segment, and there is a one-to-one correspondence between the \(K\) segments and the \(K\) trucks.
为了提高送货效率,他决定将包裹 \(1, 2, …, N\) 按此顺序排列,并将其分割为 \(K\) 个连续段(每段至少包含 \(1\) 个包裹),然后将每段中的包裹分配给一辆卡车。每个包裹恰好属于一个段,并且 \(K\) 个段与 \(K\) 辆卡车之间存在一一对应关系。
For each truck, the sum of the weights of the packages assigned to that truck is called the load of that truck.
对于每辆卡车,分配给该卡车的包裹重量之和称为该卡车的载重。
Takahashi wants to maximize the smallest load among the \(K\) trucks.
高桥希望最大化 \(K\) 辆卡车中最小的载重。
Considering all possible ways to divide the packages, find the maximum possible value of "the minimum load among the \(K\) trucks."
考虑所有可能的分割包裹方式,求"\(K\) 辆卡车中最小的载重"的最大可能值。
【输入】
\(N\) \(K\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)
- The first line contains an integer \(N\) representing the number of packages and an integer \(K\) representing the number of trucks, separated by a space.
- The second line contains \(N\) integers \(A_1, A_2, \ldots, A_N\) representing the weight of each package, separated by spaces.
【输出】
Print in one line the maximum possible value of the minimum load among the \(K\) trucks when the packages are divided optimally.
【输入样例】
5 2
1 2 3 4 5
【输出样例】
6
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100005;
int n, k; // n: 数组长度,k: 所需分段数
int a[N]; // 数组
// 检查是否能够将数组分割为至少k段,使得每段和至少为x
bool check(int x)
{
int sum = 0, ans = 0; // sum: 当前段的和,ans: 已分割的段数
for (int i = 1; i <= n; i++)
{
if (sum + a[i] >= x) // 如果将当前元素加入会使段和达到x
{
ans++; // 段数加1
sum = 0; // 重置当前段和
}
else
{
sum += a[i]; // 将当前元素加入当前段
}
}
return ans >= k; // 返回是否能分割出至少k段
}
signed main()
{
cin >> n >> k; // 读入数组长度和所需段数
for (int i = 1; i <= n; i++)
{
cin >> a[i]; // 读入数组
}
int l = 0, r = 1e18; // 二分查找范围
while (l < r) // 二分查找
{
int mid = (l + r + 1) / 2; // 计算中点
if (check(mid)) // 如果mid可行
{
l = mid; // 尝试更大的值
}
else
{
r = mid - 1; // 尝试更小的值
}
}
cout << l << endl; // 输出最大的满足条件的x
return 0;
}
【运行结果】
5 2
1 2 3 4 5
6
浙公网安备 33010602011771号