AtCoder Weekday Contest 0015 Beta题解(AWC 0015 Beta A-E)
A - Dot Product Calculation
【题目来源】
AtCoder:A - Dot Product Calculation
【题目描述】
Takahashi is practicing dot product calculations in his university linear algebra class.
高桥正在大学线性代数课上练习点积计算。
Given two \(7\)-dimensional vectors \(\mathbf{a} = (A_1, A_2, \ldots, A_7)\) and \(\mathbf{b} = (B_1, B_2, \ldots, B_7)\), compute their dot product \(\mathbf{a} \cdot \mathbf{b} = A_1 \times B_1 + A_2 \times B_2 + \cdots + A_7 \times B_7\).
给定两个 \(7\) 维向量 \(\mathbf{a} = (A_1, A_2, \ldots, A_7)\) 和 \(\mathbf{b} = (B_1, B_2, \ldots, B_7)\),计算它们的点积 \(\mathbf{a} \cdot \mathbf{b} = A_1 \times B_1 + A_2 \times B_2 + \cdots + A_7 \times B_7\)。
【输入】
\(A_1\) \(A_2\) \(A_3\) \(A_4\) \(A_5\) \(A_6\) \(A_7\)
\(B_1\) \(B_2\) \(B_3\) \(B_4\) \(B_5\) \(B_6\) \(B_7\)
- The first line contains \(7\) integers \(A_1, A_2, \ldots, A_7\) separated by spaces, representing the components of vector \(\mathbf{a}\).
- The second line contains \(7\) integers \(B_1, B_2, \ldots, B_7\) separated by spaces, representing the components of vector \(\mathbf{b}\).
【输出】
Print the value of the dot product of the two vectors, \(A_1 \times B_1 + A_2 \times B_2 + \cdots + A_7 \times B_7\), on a single line.
【输入样例】
1 2 3 4 5 6 7
1 1 1 1 1 1 1
【输出样例】
28
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 10;
int a[N], b[N], ans; // a: 第一个数组,b: 第二个数组,ans: 结果
signed main()
{
for (int i = 1; i <= 7; i++) // 读入第一个数组
{
cin >> a[i];
}
for (int i = 1; i <= 7; i++) // 读入第二个数组
{
cin >> b[i];
}
for (int i = 1; i <= 7; i++) // 计算点积
{
ans += a[i] * b[i]; // 对应元素相乘并累加
}
cout << ans << endl; // 输出结果
return 0;
}
【运行结果】
1 2 3 4 5 6 7
1 1 1 1 1 1 1
28
B - First Alert
【题目来源】
AtCoder:B - First Alert
【题目描述】
Takahashi is in charge of a server monitoring system. In this system, \(N\) logs arrive in order.
高桥负责一个服务器监控系统。在这个系统中,\(N\) 条日志按顺序到达。
Each log has an integer value representing its "severity level." The severity level of the \(i\)-th log (\(1 \leq i \leq N\)) to arrive is \(P_i\).
每条日志都有一个整数值,表示其"严重性等级"。第 \(i\) 条(\(1 ≤ i ≤ N\))到达的日志的严重性等级为 \(P_i\)。
For efficient monitoring, Takahashi has set up his own rule. He checks the logs in order starting from the 1st one, and as soon as he finds a log with a severity level of at least the threshold \(K\), he immediately triggers an alert and goes to respond. Once an alert is triggered, he does not check any subsequent logs.
为了高效监控,高桥设定了他自己的规则。他按顺序从第 \(1\) 条开始检查日志,一旦发现严重性等级不低于阈值 \(K\) 的日志,他会立即触发警报并去响应。一旦触发警报,他将不再检查任何后续日志。
Determine the number of the log (i.e., which log in the arrival order) that causes Takahashi to trigger an alert. If the severity levels of all \(N\) logs are less than \(K\) and no alert is ever triggered, output \(-1\).
确定导致高桥触发警报的日志编号(即到达顺序中的第几条日志)。如果所有 \(N\) 条日志的严重性等级都小于 \(K\),且从未触发警报,则输出 \(-1\)。
【输入】
\(N\) \(K\)
\(P_1\) \(P_2\) \(\ldots\) \(P_N\)
- The first line contains an integer \(N\) representing the number of logs and an integer \(K\) representing the severity threshold for triggering an alert, separated by a space.
- The second line contains integers \(P_1, P_2, \ldots, P_N\) representing the severity levels of each log, separated by spaces.
- \(P_i\) represents the severity level of the \(i\)-th log to arrive.
【输出】
Print the number of the log that causes Takahashi to trigger an alert, on a single line. Here, the log number is an integer between \(1\) and \(N\) inclusive, representing which log it is in the arrival order. If no alert is ever triggered, print \(-1\).
【输入样例】
5 50
10 30 55 80 20
【输出样例】
3
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, k, p[N]; // n: 数组长度,k: 阈值,p: 数组
int main()
{
cin >> n >> k; // 读入数组长度和阈值
int cnt = 1; // 变量cnt定义但未使用
for (int i = 1; i <= n; i++)
{
cin >> p[i]; // 读入数组元素
}
for (int i = 1; i <= n; i++)
{
if (p[i] >= k) // 找到第一个大于等于阈值k的元素
{
cout << i; // 输出该元素的下标
return 0; // 直接结束程序
}
}
cout << -1 << endl; // 如果没有找到,输出-1
return 0;
}
【运行结果】
5 50
10 30 55 80 20
3
C - Matchup Card Combinations
【题目来源】
AtCoder:C - Matchup Card Combinations
【题目描述】
Takahashi is creating a match schedule for a sports tournament.
高桥正在为一场体育比赛创建赛程表。
There are \(N\) players participating in the tournament, numbered from \(1\) to \(N\). Each player \(i\) \((1 \leq i \leq N)\) is assigned two integers: a "sport number" \(P_i\) and a "team number" \(Q_i\). The sport number represents the identifier of the sport the player has entered, and the team number represents the identifier of the team the player belongs to.
有 \(N\) 名选手参加比赛,编号从 \(1\) 到 \(N\)。每名选手 \(i\)(\(1 ≤ i ≤ N\))被分配了两个整数:"运动项目编号" \(P_i\) 和"团队编号" \(Q_i\)。运动项目编号表示选手所参加运动项目的标识符,团队编号表示选手所属团队的标识符。
In this tournament, player \(i\) and player \(j\) \((1 \leq i < j \leq N)\) can compete against each other only if they are entered in the same sport and belong to different teams. That is, a match is possible only when \(P_i = P_j\) and \(Q_i \neq Q_j\).
在这项比赛中,选手 \(i\) 和选手 \(j\)(\(1 ≤ i < j ≤ N\))只有当参加相同的运动项目且属于不同的团队时,才能相互比赛。也就是说,只有当 \(P_i = P_j\) 且 \(Q_i ≠ Q_j\) 时,才可能进行比赛。
Note that there may be multiple players with exactly the same combination of sport number and team number. Such players are considered distinct players distinguished by their player numbers, but since they belong to the same team, they do not satisfy the condition \(Q_i \neq Q_j\) and cannot compete against each other.
注意,可能存在多名选手的运动项目编号和团队编号的组合完全相同。这样的选手被视为不同的选手,通过选手编号区分,但由于他们属于同一团队,不满足条件 \(Q_i ≠ Q_j\),因此不能相互比赛。
Find the total number of unordered pairs of players that can compete against each other.
求可以相互比赛的无序选手对的总数。
【输入】
Input is given from standard input in the following format:
\(N\)
\(P_1\) \(Q_1\)
\(P_2\) \(Q_2\)
\(\vdots\)
\(P_N\) \(Q_N\)
The first line contains an integer \(N\) representing the number of players. In the following \(N\) lines, the \(i\)-th line \((1 \leq i \leq N)\) contains the sport number \(P_i\) and team number \(Q_i\) of player \(i\), separated by a space.
【输出】
Output the total number of unordered pairs of players that can compete against each other, in a single line.
【输入样例】
4
1 1
1 2
2 1
1 1
【输出样例】
2
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, ans;
struct Node
{
int id, q; // id: 输入的编号(实际上没用到),q: 对应的q值
};
vector<Node> a[N]; // 数组下标为p值,每个元素是一个vector,存储该p值对应的所有Node
signed main()
{
cin >> n;
// 读入n对(p,q)数据
for (int i = 1; i <= n; i++)
{
int p, q;
cin >> p >> q;
a[p].push_back({i, q}); // 将数据按p值分组存储
}
// 遍历所有可能的p值(这里假设p值范围是1到100000)
for (int i = 1; i <= 100000; i++)
{
int m = a[i].size(); // 当前p值有多少个元素
if (m <= 1) // 如果少于2个元素,无法组成对,跳过
{
continue;
}
map<int, int> mp; // 用于统计当前p值下,每个q值出现的次数
// 统计每个q值出现的次数
for (int j = 0; j < m; j++)
{
mp[a[i][j].q]++; // 将q值作为key,出现次数作为value
}
int tot = m * (m - 1) / 2; // 当前p值下所有可能的对数:组合数C(m,2)
int sum = 0; // 相同q值的对数
// 遍历统计结果
for (auto [q_val, cnt] : mp)
{
if (cnt >= 2) // 如果这个q值出现了至少2次
{
// 计算相同q值的对数:C(cnt,2)
sum += cnt * (cnt - 1) / 2;
}
}
// 不同q值的对数 = 总对数 - 相同q值的对数
ans += (tot - sum);
}
cout << ans << endl;
return 0;
}
【运行结果】
4
1 1
1 2
2 1
1 1
2
D - Assignment of Cooking Tasks
【题目来源】
AtCoder:D - Assignment of Cooking Tasks
【题目描述】
Takahashi is the manager of a food stall at his university's school festival. He manages \(N\) cooking staff members and \(M\) cooking tasks.
高桥是他大学校园节上一个小吃摊的经理。他管理着 \(N\) 名烹饪工作人员和 \(M\) 项烹饪任务。
Each cooking staff member has a "skill level"; the skill level of the \(i\)-th staff member is \(A_i\). Similarly, each cooking task has a "required skill level"; the required skill level of the \(j\)-th task is \(B_j\).
每位烹饪工作人员都有一个"技能等级";第 \(i\) 名工作人员的技能等级是 \(A_i\)。同样,每项烹饪任务都有一个"所需技能等级";第 \(j\) 项任务所需技能等级是 \(B_j\)。
A staff member can handle a task only if their skill level is at least the required skill level of the task. In other words, the \(i\)-th staff member can handle the \(j\)-th task only when \(A_i \geq B_j\).
一名工作人员只有在自身技能等级不低于任务的所需技能等级时才能处理该任务。换句话说,第 \(i\) 名工作人员可以处理第 \(j\) 项任务,当且仅当 \(A_i≥B_j\)。
Takahashi assigns staff members to tasks in a one-to-one manner. That is, each staff member can be assigned to at most \(1\) task, and each task can be assigned to at most \(1\) staff member. It is not necessary to assign a task to every staff member, and it is acceptable for some tasks to have no staff member assigned to them.
高桥以一对一的方式为任务分配工作人员。也就是说,每位工作人员最多只能被分配到 \(1\) 项任务,每项任务最多只能被分配到 \(1\) 名工作人员。并非必须为每位工作人员都分配任务,也允许某些任务未被分配工作人员。
A task to which a staff member is assigned is completed, producing \(1\) dish as a result. All completed dishes are sold at \(C\) yen each. In other words, if \(K\) tasks are completed, the total sales amount is \(K \times C\) yen.
被分配了工作人员的任务可以完成,从而生产出 \(1\) 道菜品。所有完成的菜品每道以 \(C\) 日元的价格出售。换句话说,如果完成了 \(K\) 项任务,总销售额为 \(K × C\) 日元。
Find the maximum sales amount Takahashi can obtain when he optimally chooses the assignment of staff members to tasks.
求在高桥最优地为任务分配工作人员时,他能获得的最大销售额。
【输入】
\(N\) \(M\) \(C\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)
\(B_1\) \(B_2\) \(\ldots\) \(B_M\)
- The first line contains \(N\), the number of staff members, \(M\), the number of tasks, and \(C\), the selling price per dish, separated by spaces.
- The second line contains the skill levels of each staff member, \(A_1, A_2, \ldots, A_N\), separated by spaces.
- The third line contains the required skill levels of each task, \(B_1, B_2, \ldots, B_M\), separated by spaces.
【输出】
Print the maximum sales amount Takahashi can obtain in a single line. Note that the answer is a non-negative integer not exceeding \(2 \times 10^{14}\).
【输入样例】
3 3 500
5 3 1
2 4 6
【输出样例】
1000
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, m, c; // n: 数组a的大小, m: 数组b的大小, c: 单位收益
int a[N], b[N], ans; // a[]: 第一个数组, b[]: 第二个数组, ans: 匹配数量
signed main()
{
// 读入数据
cin >> n >> m >> c;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= m; i++)
{
cin >> b[i];
}
// 对两个数组进行升序排序
sort(a + 1, a + n + 1);
sort(b + 1, b + m + 1);
int i = 1, j = 1; // i: 指向b数组的指针, j: 指向a数组的指针
// 使用双指针贪心匹配
while (i <= m && j <= n)
{
if (a[j] >= b[i]) // 如果当前a元素 >= 当前b元素,可以匹配
{
ans++; // 匹配数量加1
i++; // 移动到下一个b元素
j++; // 移动到下一个a元素
}
else // 当前a元素 < 当前b元素,a元素太小,看下一个a元素
{
j++; // 移动到下一个a元素
}
}
// 输出总收益 = 匹配数量 × 单位收益
cout << ans * c;
return 0;
}
【运行结果】
3 3 500
5 3 1
2 4 6
1000
E - Count the Types of Flowers
【题目来源】
AtCoder:E - Count the Types of Flowers
【题目描述】
Takahashi works as a caretaker at a botanical garden. The garden has \(N\) flower beds arranged in a straight line, numbered \(1, 2, \ldots, N\) from left to right. Each flower bed \(i\) \((1 \leq i \leq N)\) contains a flower of species number \(P_i\). Species numbers are integers between \(1\) and \(N\) inclusive, and different flower beds may contain flowers of the same species number.
高桥在一座植物园担任管理员。花园里有 \(N\) 个花坛排成一条直线,从左到右编号为 \(1, 2, …, N\)。每个花坛 \(i\)(\(1 ≤ i ≤ N\))包含一种编号为 \(P_i\) 的花卉。物种编号是介于 \(1\) 和 \(N\) 之间的整数,不同的花坛可能包含相同物种编号的花卉。
The botanical garden has \(Q\) tour visits scheduled. The \(i\)-th tour \((1 \leq i \leq Q)\) visits the range from flower bed \(L_i\) to flower bed \(R_i\) (inclusive).
植物园安排了 \(Q\) 次参观游览。第 \(i\) 次参观(\(1 ≤ i ≤ Q\))将访问从花坛 \(L_i\) 到花坛 \(R_i\)(包含两端)的范围。
Takahashi wants to know in advance how many distinct types of flowers are in each tour's visiting range, in order to prepare the guide for each tour.
高桥希望提前了解每次参观的访问范围内有多少种不同的花卉类型,以便为每次参观准备导览。
For each tour, determine the number of distinct species numbers contained in the range from flower bed \(L_i\) to flower bed \(R_i\).
对于每次参观,确定从花坛 \(L_i\) 到花坛 \(R_i\) 的范围内包含的不同物种编号的数量。
【输入】
\(N\) \(Q\)
\(P_1\) \(P_2\) \(\ldots\) \(P_N\)
\(L_1\) \(R_1\)
\(L_2\) \(R_2\)
\(\vdots\)
\(L_Q\) \(R_Q\)
- The first line contains an integer \(N\) representing the number of flower beds and an integer \(Q\) representing the number of tours, separated by a space.
- The second line contains integers \(P_1, P_2, \ldots, P_N\) representing the species numbers of the flowers planted in each flower bed, separated by spaces.
- The following \(Q\) lines give the visiting range for each tour.
- The \(i\)-th of these lines \((1 \leq i \leq Q)\) contains the left endpoint \(L_i\) and right endpoint \(R_i\) of the visiting range for the \(i\)-th tour, separated by a space.
【输出】
Output \(Q\) lines. The \(i\)-th line \((1 \leq i \leq Q)\) should contain the number of distinct species numbers in the range from flower bed \(L_i\) to flower bed \(R_i\) for the \(i\)-th tour.
【输入样例】
5 3
1 2 1 3 2
1 3
2 5
1 5
【输出样例】
2
3
3
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, q; // n: 数组长度,q: 查询次数
int p[N], last[N]; // p: 原数组,last: 记录每个物种上次出现的位置
int tr[N], ans[N]; // tr: 树状数组,ans: 存储查询结果
struct Node
{
int id, l, r; // 查询的编号、左边界、右边界
}Q[N];
// 计算lowbit:返回x的二进制表示中最低位的1所对应的值
int lowbit(int x)
{
return x & -x;
}
// 树状数组更新操作:在位置x增加c
void add(int x, int c)
{
for (int i = x; i <= n; i += lowbit(i))
{
tr[i] += c;
}
}
// 树状数组查询操作:查询前缀和[1, x]
int query(int x)
{
int res = 0;
for (int i = x; i; i -= lowbit(i))
{
res += tr[i];
}
return res;
}
// 查询按右端点排序的比较函数
bool cmp(Node x, Node y)
{
return x.r < y.r; // 按右端点升序排序
}
int main()
{
cin >> n >> q; // 读入数组长度和查询次数
for (int i = 1; i <= n; i++)
{
cin >> p[i]; // 读入原数组
}
for (int i = 1; i <= q; i++) // 读入查询
{
int l, r;
cin >> l >> r;
Q[i] = {i, l, r}; // 存储查询编号、左右边界
}
sort(Q + 1, Q + q + 1, cmp); // 将查询按右端点排序
int cur = 1; // 当前处理的数组位置
for (int i = 1; i <= q; i++) // 处理每个查询
{
int l = Q[i].l, r = Q[i].r, id = Q[i].id;
// 处理数组位置,直到达到当前查询的右端点
while (cur <= r)
{
int species = p[cur]; // 当前位置的物种
if (last[species] != 0) // 如果这个物种之前出现过
{
add(last[species], -1); // 在之前出现的位置-1
}
add(cur, 1); // 在当前位置+1
last[species] = cur; // 更新这个物种最后出现的位置
cur++;
}
// 查询区间[l, r]的不同物种数量
ans[id] = query(r) - query(l - 1);
}
for (int i = 1; i <= q; i++)
{
cout << ans[i] << endl; // 输出所有查询结果
}
return 0;
}
【运行结果】
5 3
1 2 1 3 2
1 3
2
2 5
3
1 5
3
浙公网安备 33010602011771号