AtCoder Weekday Contest 0029 Beta题解(AWC 0029 Beta A-E)
A - Calculating Part-Time Job Pay
【题目来源】
AtCoder:A - Calculating Part-Time Job Pay
【题目描述】
Takahashi is an accountant at a company. This company has \(N\) part-time staff members, each numbered from \(1\) to \(N\).
高桥是一家公司的会计。该公司有 \(N\) 名兼职员工,每位编号从 \(1\) 到 \(N\)。
In a certain month, staff member \(i\) worked \(C_i\) shifts.
在某个月,员工 \(i\) 工作了 \(C_i\) 个班次。
The company pays each staff member a base pay of \(P\) yen per shift. However, for staff members whose monthly shift count is \(K\) or more, a special bonus of \(B\) yen per shift is added on top of the base pay for all of that staff member's shifts. In other words, staff members with \(K\) or more monthly shifts are paid a total of \(P + B\) yen per shift, while staff members with fewer than \(K\) shifts are paid \(P\) yen per shift.
公司为每位员工每班支付 \(P\) 日元的底薪。然而,对于当月班次达到 \(K\) 个或以上的员工,在所有班次上,除了底薪外,每班还会额外增加 \(B\) 日元的特别奖金。换句话说,当月班次达到 \(K\) 个或以上的员工每班共获得 \(P + B\) 日元,而班次少于 \(K\) 的员工每班获得 \(P\) 日元。
Find the total salary to be paid to all \(N\) staff members.
求应支付给所有 \(N\) 名员工的总工资。
【输入】
\(N\) \(P\) \(B\) \(K\)
\(C_1\) \(C_2\) \(\ldots\) \(C_N\)
- The first line contains \(N\) representing the number of staff members, \(P\) representing the base pay per shift, \(B\) representing the special bonus amount per shift, and \(K\) representing the threshold of monthly shift count for the special bonus to apply, separated by spaces.
- The second line contains \(C_1, C_2, \ldots, C_N\) representing the monthly shift count of each staff member, separated by spaces.
【输出】
Print the total salary the company pays to all \(N\) staff members on a single line.
【输入样例】
3 100 50 3
5 2 3
【输出样例】
1400
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int n, p, b, k;
int ans;
int main()
{
cin >> n >> p >> b >> k;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
// 如果数量大于等于k,则单价为p+b
if (x >= k)
{
ans += (p + b) * x;
}
else
{
// 否则单价为p
ans += p * x;
}
}
cout << ans << endl;
return 0;
}
【运行结果】
3 100 50 3
5 2 3
1400
B - Warehouse Inventory Management
【题目来源】
AtCoder:B - Warehouse Inventory Management
【题目描述】
Takahashi is in charge of warehouse management at a logistics center.
高桥负责物流中心的仓库管理。
The logistics center has \(N\) warehouses, each numbered from \(1\) to \(N\). Initially, warehouse \(i\) \((1 \leq i \leq N)\) stores exactly one item with weight \(V_i\).
物流中心有 \(N\) 个仓库,编号从 \(1\) 到 \(N\)。初始时,仓库 \(i\)(\(1 \leq i \leq N\))恰好存放着一个重量为 \(V_i\) 的物品。
Aoki is in charge of delivery and gives \(Q\) instructions to Takahashi in order. Each instruction is one of the following two types:
青木负责配送,并按顺序向高桥发出 \(Q\) 条指令。每条指令是以下两种类型之一:
- Type 1: "Move all items in warehouse \(a\) to warehouse \(b\)" (\(a \neq b\)). All items currently in warehouse \(a\) are moved to warehouse \(b\). After the move, warehouse \(a\) becomes empty. Warehouse \(b\) will then store both the items it originally had and the items moved from warehouse \(a\). If warehouse \(a\) is empty, nothing happens.
类型 1:"将仓库 \(a\) 中的所有物品移动到仓库 \(b\)"(\(a \neq b\))。当前仓库 \(a\) 中的所有物品都将被移动到仓库 \(b\)。移动后,仓库 \(a\) 变为空。仓库 \(b\) 将存放其原有物品以及从仓库 \(a\) 移来的物品。如果仓库 \(a\) 为空,则不进行任何操作。 - Type 2: "Report the total weight of items in warehouse \(c\)". Output the total weight of all items currently stored in warehouse \(c\). If warehouse \(c\) is empty, output \(0\).
类型 2:"报告仓库 \(c\) 中物品的总重量"。输出当前仓库 \(c\) 中存放的所有物品的总重量。如果仓库 \(c\) 为空,则输出 \(0\)。
Takahashi processes the instructions in order starting from the first. For each Type 2 instruction, determine the value that should be output.
高桥从第一条开始按顺序处理指令。对于每条类型 2 的指令,确定应输出的值。
【输入】
\(N\) \(Q\)
\(V_1\) \(V_2\) \(\ldots\) \(V_N\)
\(\text{query}_1\)
\(\text{query}_2\)
\(\vdots\)
\(\text{query}_Q\)
- The first line contains two space-separated integers: \(N\), the number of warehouses, and \(Q\), the number of instructions.
- The second line contains \(N\) space-separated integers \(V_1, V_2, \ldots, V_N\), where \(V_i\) represents the weight of the item initially stored in warehouse \(i\).
- The following \(Q\) lines each contain one instruction. Each instruction \(\text{query}_i\) is in one of the following formats:
- Type 1:
1 a b(move all items from warehouse \(a\) to warehouse \(b\)) - Type 2:
2 c(find the total weight of items in warehouse \(c\))
【输出】
For each Type 2 instruction, output the corresponding value on a separate line, in the order the instructions were given. If there are no Type 2 instructions, output nothing.
【输入样例】
3 5
10 20 30
1 1 2
2 2
2 1
1 3 2
2 2
【输出样例】
30
0
60
【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, q;
int v[N]; // 存储每个位置的值
signed main()
{
cin >> n >> q;
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
while (q--)
{
int op, a, b, c;
cin >> op;
if (op == 1)
{
cin >> a >> b;
// 将a位置的值加到b位置,然后将a位置清零
v[b] += v[a];
v[a] = 0;
}
else
{
cin >> c;
// 查询c位置的值
cout << v[c] << endl;
}
}
return 0;
}
【运行结果】
3 5
10 20 30
1 1 2
2 2
30
2 1
0
1 3 2
2 2
60
C - Formation of the Strongest Pair
【题目来源】
AtCoder:C - Formation of the Strongest Pair
【题目描述】
Takahashi is preparing for a team programming contest and has decided to select \(2\) different people from the members to form one pair.
高桥正在为一场团队编程比赛做准备,并决定从成员中选出 \(2\) 个不同的人组成一对。
The team has \(N\) members, and the \(i\)-th member (\(1 \leq i \leq N\)) has a positive integer value \(A_i\) representing their programming ability. Note that different members may have the same ability value, but as long as they are different people, they can be distinguished and selected for a pair.
团队有 \(N\) 名成员,第 \(i\) 名成员(\(1 \leq i \leq N\))有一个表示其编程能力的正整数值 \(A_i\)。注意,不同的成员可能具有相同的能力值,但只要他们是不同的人,就可以被区分并选为一对。
The "combined strength" of a pair consisting of the \(i\)-th member and the \(j\)-th member (\(1 \leq i < j \leq N\)) is defined as the sum of their ability values, \(A_i + A_j\).
由第 \(i\) 名成员和第 \(j\) 名成员(\(1 \leq i < j \leq N\))组成的"组合实力"定义为他们的能力值之和,即 \(A_i + A_j\)。
Takahashi wants to select a pair that maximizes the combined strength.
高桥希望选出一对能够最大化组合实力。
Find the maximum possible value of the pair's combined strength.
求这对组合实力的最大可能值。
【输入】
\(N\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)
- The first line contains an integer \(N\) representing the number of members.
- The second line contains \(N\) integers \(A_1, A_2, \ldots, A_N\) separated by spaces, representing the ability values of each member.
【输出】
Print the maximum possible value of the pair's combined strength on one line.
【输入样例】
5
3 1 4 1 5
【输出样例】
9
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n;
int a[N];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
// 从大到小排序
sort(a + 1, a + n + 1, greater<int>());
// 输出最大的两个数的和
cout << a[1] + a[2] << endl;
return 0;
}
【运行结果】
5
3 1 4 1 5
9
D - Network Installation
【题目来源】
AtCoder:D - Network Installation
【题目描述】
Takahashi is working as a network engineer at a telecommunications company and is in charge of planning the installation of fiber optic cables.
高桥在一家电信公司担任网络工程师,负责规划光纤电缆的安装。
There are \(N\) relay stations in the city, numbered from \(1\) to \(N\). There are also \(M\) underground tunnels, each connecting two different relay stations bidirectionally. The \(i\)-th tunnel \((1 \leq i \leq M)\) connects relay station \(U_i\) and relay station \(V_i\), and has a width of \(W_i\) centimeters.
该城市有 \(N\) 个中继站,编号从 \(1\) 到 \(N\)。还有 \(M\) 条地下隧道,每条隧道双向连接两个不同的中继站。第 \(i\) 条隧道(\(1 \leq i \leq M\))连接中继站 \(U_i\) 和中继站 \(V_i\),宽度为 \(W_i\) 厘米。
Takahashi wants to install a fiber optic cable bundle of width \(K\) centimeters from the data center at relay station \(1\) to the customer building at relay station \(N\). In order to pass the cable bundle through a tunnel, the width of that tunnel must be at least \(K\) centimeters. Therefore, all tunnels along the installation route must have a width of at least \(K\) centimeters.
高桥希望安装一条宽度为 \(K\) 厘米的光纤电缆束,从中继站 \(1\) 的数据中心连接到中继站 \(N\) 的客户大楼。为了让电缆束通过一条隧道,该隧道的宽度必须不小于 \(K\) 厘米。因此,安装路径上的所有隧道宽度都必须至少为 \(K\) 厘米。
Here, a path from relay station \(1\) to relay station \(N\) is a sequence of relay stations \(v_0, v_1, \ldots, v_L\) (\(L \geq 1\)) satisfying all of the following conditions:
这里,从中继站 \(1\) 到中继站 \(N\) 的一条路径是一个满足以下所有条件的中继站序列 \(v_0, v_1, \ldots, v_L\)(\(L \geq 1\)):
- \(v_0 = 1\) and \(v_L = N\).
- For each \(j\) (\(1 \leq j \leq L\)), there exists a tunnel connecting relay station \(v_{j-1}\) and relay station \(v_j\).
对于每个 \(j\)(\(1 \leq j \leq L\)),存在一条隧道连接中继站 \(v_{j-1}\) 和中继站 \(v_j\)。 - \(v_0, v_1, \ldots, v_L\) are all distinct (no relay station is visited more than once).
\(v_0, v_1, \ldots, v_L\) 互不相同(不重复访问任何中继站)。
This path passes through \(L\) tunnels. We call this \(L\) the number of tunnels traversed by the path.
这条路径经过 \(L\) 条隧道。我们称 \(L\) 为该路径经过的隧道数量。
To reduce costs, Takahashi wants to minimize the number of tunnels traversed.
为了降低成本,高桥希望最小化经过的隧道数量。
Determine whether there exists a path where all tunnels along the path have a width of at least \(K\) centimeters. If such a path exists, output the minimum number of tunnels traversed among all such paths. If no such path exists, output -1.
判断是否存在一条路径,使得该路径上的所有隧道宽度都至少为 \(K\) 厘米。如果存在这样的路径,输出所有此类路径中经过的最小隧道数量。如果不存在这样的路径,输出 -1。
【输入】
\(N\) \(M\) \(K\)
\(U_1\) \(V_1\) \(W_1\)
\(U_2\) \(V_2\) \(W_2\)
\(\vdots\)
\(U_M\) \(V_M\) \(W_M\)
The first line contains the number of relay stations \(N\), the number of tunnels \(M\), and the width of the cable bundle \(K\) (in centimeters), separated by spaces.
The \(i\)-th of the following \(M\) lines \((1 \leq i \leq M)\) contains the numbers of the two relay stations \(U_i\), \(V_i\) connected by the \(i\)-th tunnel, and the width \(W_i\) (in centimeters) of that tunnel, separated by spaces.
【输出】
If there exists a path from relay station \(1\) to relay station \(N\) where all tunnels along the path have a width of at least \(K\) centimeters, output the minimum number of tunnels traversed among all such paths on a single line.
If no such path exists, output -1.
【输入样例】
5 6 5
1 2 3
1 3 7
2 5 10
3 4 6
4 5 8
1 5 2
【输出样例】
3
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 200005, M = N * 2;
int n, m, k;
// 邻接表存储图
int h[N], e[M], w[M], ne[M], idx;
int dist[N]; // 存储从起点到每个点的最短距离
// 添加边
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
// 广度优先搜索
void bfs()
{
queue<int> q;
memset(dist, -1, sizeof(dist)); // 初始化距离为-1表示未访问
q.push(1);
dist[1] = 0; // 起点到自己的距离为0
while (!q.empty())
{
int u = q.front();
q.pop();
// 遍历u的所有邻接点
for (int i = h[u]; i != -1; i = ne[i])
{
int v = e[i];
// 如果v未被访问过
if (dist[v] == -1)
{
q.push(v);
dist[v] = dist[u] + 1; // 更新距离
}
}
}
}
int main()
{
cin >> n >> m >> k;
memset(h, -1, sizeof(h)); // 初始化邻接表
for (int i = 1; i <= m; i++)
{
int u, v, w;
cin >> u >> v >> w;
// 只添加边权大于等于k的边
if (w >= k)
{
add(u, v, w), add(v, u, w);
}
}
bfs(); // 从起点1开始BFS
cout << dist[n] << endl; // 输出起点到n点的最短距离
return 0;
}
【运行结果】
5 6 5
1 2 3
1 3 7
2 5 10
3 4 6
4 5 8
1 5 2
3
E - Traveling Delivery
【题目来源】
AtCoder:E - Traveling Delivery
【题目描述】
Takahashi works as a delivery person. His assigned area has \(N\) locations, numbered from location \(1\) to location \(N\). There are \(M\) one-way roads between locations, and the \(i\)-th road \((1 \leq i \leq M)\) can only be traversed from location \(U_i\) to location \(V_i\), with a positive cost of \(W_i\). Takahashi moves between locations using only these roads.
高桥是一名送货员。他负责的区域有 \(N\) 个地点,编号从 \(1\) 到 \(N\)。地点之间有 \(M\) 条单向道路,第 \(i\) 条道路(\(1 \leq i \leq M\))只能从地点 \(U_i\) 行驶到地点 \(V_i\),正成本为 \(W_i\)。高桥只能使用这些道路在地点间移动。
Takahashi is currently at the office located at location \(S\). As today's task, he needs to deliver packages to \(K\) destinations \(T_1, T_2, \ldots, T_K\). These destinations are all distinct from each other and all different from location \(S\).
高桥目前位于地点 \(S\) 的办公室。作为今天的任务,他需要将包裹递送到 \(K\) 个目的地 \(T_1, T_2, \ldots, T_K\)。这些目的地彼此不同,且都与地点 \(S\) 不同。
Takahashi departs from location \(S\), visits all \(K\) destinations in any order he likes to deliver the packages, and must finally return to the office at location \(S\). Here, Takahashi's route is a sequence of roads starting from location \(S\), traversing roads one by one (such that the endpoint of each road matches the starting point of the next road), and ultimately arriving back at location \(S\). A package is considered delivered to a destination as long as Takahashi passes through that destination's location at least once during the route from departure to return. That is, merely passing through a destination location is sufficient.
高桥从地点 \(S\) 出发,按照他喜欢的任意顺序访问所有 \(K\) 个目的地以递送包裹,最后必须返回地点 \(S\) 的办公室。这里,高桥的路线是从地点 \(S\) 开始,依次经过道路(使得每条道路的终点与下一条道路的起点相同),最终返回地点 \(S\) 的一个序列。只要高桥在从出发到返回的路线中至少经过一次目的地所在的地点,即视为包裹已送达该目的地。也就是说,仅仅经过目的地地点就足够了。
During the journey, it is permitted to traverse the same road or visit the same location multiple times. However, if the same road is traversed multiple times, its cost is incurred each time.
在旅程中,允许多次经过同一条道路或多次访问同一地点。但是,如果同一条道路被经过多次,每次经过都会产生相应的成本。
Find the minimum total cost of roads traversed (where the cost of a road traversed multiple times is counted for each traversal) over all possible routes where Takahashi departs from location \(S\), visits all \(K\) destinations, and returns to location \(S\). If it is impossible to visit all destinations and return to location \(S\), output -1.
求高桥从地点 \(S\) 出发,访问所有 \(K\) 个目的地,并返回地点 \(S\) 的所有可能路线中,经过道路的最小总成本(其中道路被多次经过时,每次经过的成本都计入)。如果无法访问所有目的地并返回地点 \(S\),则输出 -1。
【输入】
\(N\) \(M\)
\(U_1\) \(V_1\) \(W_1\)
\(U_2\) \(V_2\) \(W_2\)
\(\vdots\)
\(U_M\) \(V_M\) \(W_M\)
\(S\) \(K\)
\(T_1\) \(T_2\) \(\ldots\) \(T_K\)
- The first line contains the number of locations \(N\) and the number of roads \(M\), separated by a space.
- The following \(M\) lines each contain, for the \(i\)-th road \((1 \leq i \leq M)\), the starting point \(U_i\), the ending point \(V_i\), and the cost \(W_i\), separated by spaces.
- The next line contains Takahashi's starting location \(S\) and the number of destinations \(K\), separated by a space.
- The next line contains the destination locations \(T_1, T_2, \ldots, T_K\), separated by spaces.
【输出】
Output in a single line the minimum total cost of roads traversed for Takahashi to visit all destinations and return to location \(S\). If it is impossible to visit all destinations and return to location \(S\), output -1.
【输入样例】
4 5
1 2 3
2 3 2
3 1 4
1 3 10
2 1 5
1 2
2 3
【输出样例】
9
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 305, M = N * N, INF = 1e18;
int n, m;
int h[N], e[M], w[M], ne[M], idx;
int s, k;
int t[20];
int dist[N][N], dp[(1 << 16)][N];
signed main()
{
cin >> n >> m;
// 初始化距离矩阵
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
{
dist[i][j] = 0;
}
else
{
dist[i][j] = INF;
}
}
}
// 读入边
for (int i = 1; i <= m; i++)
{
int u, v, w;
cin >> u >> v >> w;
dist[u][v] = min(dist[u][v], w);
}
// Floyd算法计算所有点对最短距离
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
cin >> s >> k;
for (int i = 1; i <= k; i++)
{
cin >> t[i];
}
// 初始化DP数组
for (int mask = 0; mask < (1 << k); mask++)
{
for (int i = 1; i <= k; i++)
{
dp[mask][i] = INF;
}
}
// 初始化状态:从起点s出发,只访问一个目标点
for (int i = 1; i <= k; i++)
{
dp[1 << (i - 1)][i] = dist[s][t[i]];
}
// 状态转移
for (int mask = 0; mask < (1 << k); mask++)
{
for (int u = 1; u <= k; u++)
{
if (dp[mask][u] == INF)
{
continue;
}
for (int v = 1; v <= k; v++)
{
// 如果v已经在访问集合中,跳过
if (mask & (1 << (v - 1)))
{
continue;
}
int new_mask = mask | (1 << (v - 1));
int new_value = dp[mask][u] + dist[t[u]][t[v]];
if (new_value < dp[new_mask][v])
{
dp[new_mask][v] = new_value;
}
}
}
}
// 计算最终答案:访问完所有点后回到起点s
int ans = INF;
for (int i = 1; i <= k; i++)
{
ans = min(ans, dp[(1 << k) - 1][i] + dist[t[i]][s]);
}
if (ans == INF)
{
cout << -1 << endl;
}
else
{
cout << ans << endl;
}
return 0;
}
【运行结果】
4 5
1 2 3
2 3 2
3 1 4
1 3 10
2 1 5
1 2
2 3
9
浙公网安备 33010602011771号