AtCoder Weekday Contest 0003 Beta题解(AWC 0003 Beta A-E)
A - Product Quality Evaluation
【题目来源】
AtCoder:A - Product Quality Evaluation
【题目描述】
Takahashi is in charge of quality control at a factory. This factory manufactures \(N\) types of products, each numbered from \(1\) to \(N\).
高桥负责一家工厂的质量控制工作。这家工厂生产 \(N\) 种产品,每种产品编号从 \(1\) 到 \(N\)。
Each product has two metrics: a "quality index" and a "production quantity." The quality index of product \(i\) is \(A_i\), and its daily production quantity is \(B_i\) units. A higher quality index indicates that defective items are more likely to occur.
每种产品有两个指标:"质量指数"和"生产数量"。产品 \(i\) 的质量指数为 \(A_i\),其日生产数量为 \(B_i\) 单位。质量指数越高,表明次品出现的可能性越大。
Takahashi decided to calculate a "risk score" for each product. The risk score of product \(i\) is defined as the product of the quality index \(A_i\) and the production quantity \(B_i\), namely \(A_i \times B_i\). A higher risk score means that more attention is required for that product.
高桥决定为每种产品计算一个"风险分数"。产品 \(i\) 的风险分数定义为质量指数 \(A_i\) 与生产数量 \(B_i\) 的乘积,即 \(A_i × B_i\)。风险分数越高,意味着该产品需要更多关注。
Takahashi believes that products with a risk score of \(K\) or higher need to be prioritized for improvement. Find the number of products whose risk score is \(K\) or higher.
高桥认为,风险分数为 \(K\) 或更高的产品需要优先进行改进。求风险分数为 \(K\) 或更高的产品数量。
【输入】
\(N\) \(K\)
\(A_1\) \(B_1\)
\(A_2\) \(B_2\)
\(\vdots\)
\(A_N\) \(B_N\)
- The first line contains an integer \(N\) representing the number of product types and an integer \(K\) representing the risk score threshold, separated by a space.
- From the 2nd line to the \((N+1)\)-th line, information about each product is given.
- The \((i+1)\)-th line \((1 \leq i \leq N)\) contains the quality index \(A_i\) and the production quantity \(B_i\) of product \(i\), separated by a space.
【输出】
Output the number of products whose risk score is \(K\) or higher, in a single line.
【输入样例】
3 100
10 5
20 10
5 30
【输出样例】
2
【解题思路】

【代码详解】
#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 a, b; // a: 单价,b: 数量
cin >> a >> b; // 读入单价和数量
if (a * b >= k) // 如果总价大于等于目标金额k
{
ans++; // 计数器加1
}
}
cout << ans << endl; // 输出满足条件的商品数量
return 0;
}
【运行结果】
3 100
10 5
20 10
5 30
2
B - Line of Handshakes
【题目来源】
AtCoder:B - Line of Handshakes
【题目描述】
Takahashi is observing an interesting phenomenon at a party venue.
高桥正在派对会场观察一个有趣的现象。
\(N\) participants are standing in a line, all facing the same direction (to the right), and are numbered \(1, 2, \ldots, N\) from left to right. Each participant is wearing a glove on their left hand and right hand (from their own perspective). The color of each glove is either navy or white. In the input, navy is represented by N (Navy) and white is represented by S (Snow).
\(N\) 名参与者站成一排,全部面向同一方向(右侧),从左到右编号为 \(1, 2, …, N\)。每名参与者在其左手和右手上各戴有一只手套(从参与者自身视角)。每只手套的颜色为深蓝色或白色。在输入中,深蓝色用 N(Navy)表示,白色用 S(Snow)表示。
> Note: The character N representing the navy color and the integer \(N\) representing the number of participants are different things. Please be careful not to confuse them.
注意:表示深蓝色的字符
N与表示参与者数量的整数 \(N\) 是不同的概念。请注意不要混淆。
The color of participant \(i\)'s left-hand glove is given as \(L_i\), and the color of their right-hand glove is given as \(R_i\).
参与者 \(i\) 的左手手套颜色由 \(L_i\) 给出,其右手手套颜色由 \(R_i\) 给出。
Since all participants are standing in a line facing the same direction, when two adjacent participants shake hands, the right hand of the left participant (the one with the smaller number) and the left hand of the right participant (the one with the larger number) touch each other. If the colors of the two gloves that touch are the same (both navy or both white), this is called an awkward handshake.
由于所有参与者站成一排且面向同一方向,当两名相邻参与者握手时,左侧参与者(编号较小者)的右手与右侧参与者(编号较大者)的左手会相互接触。如果接触的两只手套颜色相同(均为深蓝色或均为白色),则称为尴尬握手。
Takahashi wants to know the number of adjacent participant pairs that result in an awkward handshake.
高桥想知道会导致尴尬握手的相邻参与者对数。
Specifically, for each \(i = 1, 2, \ldots, N-1\), check whether the color of participant \(i\)'s right-hand glove \(R_i\) and the color of participant \(i+1\)'s left-hand glove \(L_{i+1}\) are the same, and find the number of such \(i\).
具体而言,对于每个 \(i = 1, 2, …, N-1\),检查参与者 \(i\) 的右手手套颜色 \(R_i\) 与参与者 \(i+1\) 的左手手套颜色 \(L_{i+1}\) 是否相同,并统计满足条件的 \(i\) 的数量。
【输入】
\(N\)
\(L_1\) \(R_1\)
\(L_2\) \(R_2\)
\(\vdots\)
\(L_N\) \(R_N\)
- The first line contains an integer \(N\) representing the number of participants.
- In the following \(N\) lines, the \(i\)-th line \((1 \leq i \leq N)\) contains the character \(L_i\) representing the color of participant \(i\)'s left-hand glove and the character \(R_i\) representing the color of participant \(i\)'s right-hand glove, separated by a space. Each of \(L_i\) and \(R_i\) is either
N(navy) orS(white).
【输出】
Print the number of adjacent participant pairs that result in an awkward handshake, in a single line.
【输入样例】
4
N S
S N
N N
S S
【输出样例】
2
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, ans; // n: 物品数量,ans: 计数器
char l[N], r[N]; // l: 左颜色数组,r: 右颜色数组
int main()
{
cin >> n; // 读入物品数量
for (int i = 1; i <= n; i++)
{
cin >> l[i] >> r[i]; // 读入第i个物品的左颜色和右颜色
}
// 检查相邻两个物品的连接处颜色是否相同
for (int i = 1; i < n; i++)
{
if (r[i] == l[i + 1]) // 如果前一个物品的右颜色等于后一个物品的左颜色
{
ans++; // 计数器加1
}
}
cout << ans << endl; // 输出颜色相同的连接处数量
return 0;
}
【运行结果】
4
N S
S N
N N
S S
2
C - Bargain Sale Selection
【题目来源】
AtCoder:C - Bargain Sale Selection
【题目描述】
Takahashi will purchase all \(N\) items, one of each.
高桥将购买全部 \(N\) 件商品,每样一件。
Each item has two prices: a "regular price" and a "sale price." The regular price of item \(i\) \((1 \leq i \leq N)\) is \(A_i\) yen, and the sale price is \(B_i\) yen. It is guaranteed that the sale price is at most the regular price, that is, \(B_i \leq A_i\).
每件商品有两种价格:"原价"和"促销价"。商品 \(i\)(\(1 ≤ i ≤ N\))的原价为 \(A_i\) 日元,促销价为 \(B_i\) 日元。保证促销价不超过原价,即 \(B_i ≤ A_i\)。
Takahashi has one special discount coupon. With this coupon, he can choose at most \(K\) items from the \(N\) items and purchase the chosen items at their sale prices. The remaining items that are not chosen will be purchased at their regular prices. Note that the same item cannot be chosen more than once, and it is also allowed to choose no items (i.e., choose \(0\) items).
高桥有一张特殊折扣券。使用此券,他可以从 \(N\) 件商品中最多选择 \(K\) 件,并以促销价购买选中的商品。未选中的剩余商品将按原价购买。注意,同一件商品不能被选择超过一次,并且也可以选择 \(0\) 件商品(即选择 \(0\) 件)。
When Takahashi optimally chooses which items to purchase at the sale price, find the minimum possible total cost of purchasing all \(N\) items.
当高桥以最优方式选择哪些商品以促销价购买时,求购买全部 \(N\) 件商品的最小可能总费用。
【输入】
\(N\) \(K\)
\(A_1\) \(B_1\)
\(A_2\) \(B_2\)
\(\vdots\)
\(A_N\) \(B_N\)
- The first line contains an integer \(N\) representing the number of items and an integer \(K\) representing the maximum number of items that can be purchased at the sale price, separated by a space.
- The following \(N\) lines each contain, for the \(i\)-th line \((1 \leq i \leq N)\), the regular price \(A_i\) and the sale price \(B_i\) of item \(i\), separated by a space.
【输出】
Print the minimum possible total cost of purchasing all \(N\) items as an integer on a single line. Note that the answer may not fit within a \(32\)-bit integer.
【输入样例】
3 2
100 80
200 150
300 250
【输出样例】
500
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, k, ans; // n: 物品数量,k: 打折商品数量,ans: 总花费
struct Node
{
int A, B; // A: 正常价格,B: 打折后价格
}a[N];
// 比较函数:按照 (A-B) 的差值从大到小排序
// 即优先选择打折节省更多的商品
bool cmp(Node x, Node y)
{
return x.A - x.B > y.A - y.B;
}
signed main()
{
cin >> n >> k; // 读入商品总数和打折商品数量
for (int i = 1; i <= n; i++)
{
cin >> a[i].A >> a[i].B; // 读入正常价格和打折后价格
}
// 按照差价从大到小排序
sort(a + 1, a + n + 1, cmp);
// 前k个商品选择打折价
for (int i = 1; i <= k; i++)
{
ans += a[i].B;
}
// 剩余商品选择原价
for (int i = k + 1; i <= n; i++)
{
ans += a[i].A;
}
cout << ans << endl; // 输出最小总花费
return 0;
}
【运行结果】
3 2
100 80
200 150
300 250
500
D - Consecutive Practice Days
【题目来源】
AtCoder:D - Consecutive Practice Days
【题目描述】
Takahashi is the manager of the track and field club, and he manages the practice records of the club members.
高桥是田径俱乐部的经理,负责管理俱乐部会员的练习记录。
The track and field club has a practice period of \(N\) days, and each day is numbered from \(1\) to \(N\). On day \(i\) \((1 \leq i \leq N)\), a positive integer \(A_i\) representing the "practice intensity" for that day is recorded.
田径俱乐部的练习期为 \(N\) 天,每天从 \(1\) 到 \(N\) 编号。在第 \(i\) 天(\(1 ≤ i ≤ N\)),记录了一个表示当天"练习强度"的正整数 \(A_i\)。
According to the club's rules, a period consisting of \(r - l + 1\) consecutive days from day \(l\) to day \(r\) is called an "achievement period" and is specially recognized if its length is at least \(K\) days and the total practice intensity within the period is at least the target value \(M\).
根据俱乐部规定,由第 \(l\) 天到第 \(r\) 天的连续 \(r-l+1\) 天组成的时间段称为"成就期",如果其长度至少为 \(K\) 天且该时间段内的总练习强度至少达到目标值 \(M\),则会被特别认可。
Takahashi wants to find out how many achievement periods qualify for recognition.
高桥想知道有多少个成就期符合认可条件。
Specifically, find the number of integer pairs \((l, r)\) that satisfy all of the following conditions:
具体而言,求满足以下所有条件的整数对 \((l, r)\) 的数量:
- \(1 \leq l \leq r \leq N\)
- \(r - l + 1 \geq K\) (the length of the period is at least \(K\) days)
- \(A_l + A_{l+1} + \cdots + A_r \geq M\) (the total practice intensity within the period is at least \(M\))
【输入】
\(N\) \(K\) \(M\)
\(A_1\) \(A_2\) \(\cdots\) \(A_N\)
- The first line contains an integer \(N\) representing the number of days in the practice period, an integer \(K\) representing the minimum length of a period, and an integer \(M\) representing the target value for the total practice intensity, separated by spaces.
- The second line contains \(N\) integers \(A_1, A_2, \ldots, A_N\) representing the practice intensity for each day, separated by spaces.
【输出】
Print the number of integer pairs \((l, r)\) that satisfy the conditions, on a single line.
【输入样例】
5 2 10
3 5 4 2 6
【输出样例】
6
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, k, m, ans; // n: 数组长度,k: 最小长度,m: 目标和
int a[N], sa[N]; // a: 原始数组,sa: 前缀和数组
signed main()
{
cin >> n >> k >> m; // 读入数组长度、最小长度和目标总和
for (int i = 1; i <= n; i++)
{
cin >> a[i]; // 读入数组元素
sa[i] = sa[i - 1] + a[i]; // 计算前缀和
}
// 双指针算法,计算满足条件的子数组数量
for (int i = 1, j = 1; i <= n; i++) // i为子数组左端点
{
// 移动右端点j,直到找到满足条件的子数组
while (j <= n && (sa[j] - sa[i - 1] < m || j - i + 1 < k))
{
j++;
}
// 调试输出
// cout << "i j " << i << " " << j << endl;
// 如果找到了满足条件的子数组,计算以i为左端点的子数组个数
// 从j到n的所有位置都可以作为右端点
ans += (n - j + 1);
}
cout << ans << endl; // 输出满足条件的子数组个数
return 0;
}
【运行结果】
5 2 10
3 5 4 2 6
6
E - Cargo Delivery Truck
【题目来源】
AtCoder:E - Cargo Delivery Truck
【题目描述】
Takahashi works at a shipping company. Today, he needs to deliver \(N\) packages from the distribution center to their destinations. Each package is numbered from \(1\) to \(N\), and package \(i\) weighs \(W_i\) kilograms.
高桥在一家货运公司工作。今天,他需要将 \(N\) 个包裹从配送中心运送到各自的目的地。每个包裹编号从 \(1\) 到 \(N\),且包裹 \(i\) 的重量为 \(W_i\) 千克。
The distribution center has \(M\) trucks, each numbered from \(1\) to \(M\). Truck \(j\) has a maximum load capacity of \(C_j\) kilograms, meaning the total weight of packages loaded onto that truck must not exceed \(C_j\) kilograms. There is no limit on the number of packages loaded onto each truck, and it is acceptable for a truck to carry no packages at all.
配送中心有 \(M\) 辆卡车,每辆卡车编号从 \(1\) 到 \(M\)。卡车 \(j\) 的最大载重能力为 \(C_j\) 千克,这意味着装载到该卡车上的包裹总重量不得超过 \(C_j\) 千克。每辆卡车装载的包裹数量没有限制,且允许卡车完全不装载任何包裹。
Each package cannot be split and must be loaded onto exactly one truck. Determine whether it is possible to load all \(N\) packages onto the trucks without exceeding any truck's maximum load capacity.
每个包裹不可拆分,且必须装载到恰好一辆卡车上。判断是否有可能将所有 \(N\) 个包裹装载到卡车上,且不超出任何卡车的最大载重能力。
【输入】
\(N\) \(M\)
\(W_1\) \(W_2\) \(\ldots\) \(W_N\)
\(C_1\) \(C_2\) \(\ldots\) \(C_M\)
- The first line contains \(N\), the number of packages, and \(M\), the number of trucks, separated by a space.
- The second line contains \(W_1, W_2, \ldots, W_N\), the weights of the packages, separated by spaces.
- The third line contains \(C_1, C_2, \ldots, C_M\), the maximum load capacities of the trucks, separated by spaces.
【输出】
If it is possible to load all packages onto the trucks, print Yes; otherwise, print No.
【输入样例】
3 2
3 5 2
6 4
【输出样例】
No
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 20;
int n, m; // n: 货物数量,m: 箱子数量
int w[N], c[N], total_weight, total_capacity; // w: 货物重量,c: 箱子容量
bool flag; // 标记是否能装下所有货物
// 深度优先搜索,尝试将所有货物放入箱子
void dfs(int step) // step: 当前处理的货物编号
{
if (flag) // 如果已经找到一种方案,直接返回
{
return;
}
if (step > n) // 所有货物都成功放入箱子
{
flag = 1; // 标记找到可行方案
return;
}
for (int i = 1; i <= m; i++) // 尝试将当前货物放入每个箱子
{
if (c[i] >= w[step]) // 如果箱子容量足够
{
c[i] -= w[step]; // 放入货物
dfs(step + 1); // 处理下一个货物
c[i] += w[step]; // 回溯,取出货物
}
}
}
signed main()
{
cin >> n >> m; // 读入货物数量和箱子数量
for (int i = 1; i <= n; i++)
{
cin >> w[i]; // 读入货物重量
total_weight += w[i]; // 计算总重量
}
for (int i = 1; i <= m; i++)
{
cin >> c[i]; // 读入箱子容量
total_capacity += c[i]; // 计算总容量
}
// 剪枝1: 如果货物总重量大于箱子总容量,不可能装下
if (total_weight > total_capacity)
{
cout << "No" << endl;
return 0;
}
// 排序:货物从重到轻,箱子从大到小
sort(w + 1, w + n + 1, greater<int>());
sort(c + 1, c + m + 1, greater<int>());
// 剪枝2: 如果最重的货物大于最大箱子的容量,不可能装下
if (w[1] > c[1])
{
cout << "No" << endl;
return 0;
}
dfs(1); // 从第一个货物开始搜索
if (flag) // 如果找到可行方案
{
cout << "Yes" << endl;
}
else // 否则
{
cout << "No" << endl;
}
return 0;
}
【运行结果】
3 2
3 5 2
6 4
No
浙公网安备 33010602011771号