AtCoder Weekday Contest 0024 Beta题解(AWC 0024 Beta A-E)

A - Comparing Test Scores

【题目来源】

AtCoder:A - Comparing Test Scores

【题目描述】

A math test was recently held in Aoki's class. There are \(N\) students in the class, each assigned a student number from \(1\) to \(N\). The test score of student \(i\) \((1 \leq i \leq N)\) is \(S_i\) points.
青木所在的班级最近举行了一次数学测验。班上有 \(N\) 名学生,每名学生被分配了从 \(1\)\(N\) 的学生编号。学生 \(i\)\(1 \leq i \leq N\))的测验成绩为 \(S_i\) 分。

Aoki has been asked by the teacher to organize the students' grades. Aoki needs to answer \(Q\) questions. For the \(i\)-th question, he determines whether the score of the student with student number \(a_i\) is strictly higher than the score of the student with student number \(b_i\). Here, "strictly higher" means that equality is not included, i.e., \(S_{a_i} > S_{b_i}\) holds. Note that \(a_i = b_i\) is possible, meaning a comparison of the same student with themselves may occur.
老师请青木整理学生的成绩。青木需要回答 \(Q\) 个问题。对于第 \(i\) 个问题,他需要判断学号为 \(a_i\) 的学生的成绩是否严格高于学号为 \(b_i\) 的学生的成绩。这里,"严格高于"意味着不包括相等,即 \(S_{a_i} > S_{b_i}\) 成立。注意,\(a_i = b_i\) 是可能的,这意味着可能发生同一名学生自身的比较。

For each question, output Yes if \(S_{a_i} > S_{b_i}\), and No otherwise (i.e., if \(S_{a_i} \leq S_{b_i}\)).
对于每个问题,如果 \(S_{a_i} > S_{b_i}\) 则输出 Yes,否则(即 \(S_{a_i} \leq S_{b_i}\))输出 No

【输入】

\(N\) \(Q\)
\(S_1\) \(S_2\) \(\ldots\) \(S_N\)
\(a_1\) \(b_1\)
\(a_2\) \(b_2\)
\(\vdots\)
\(a_Q\) \(b_Q\)

  • The first line contains an integer \(N\) representing the number of students and an integer \(Q\) representing the number of questions, separated by a space.
  • The second line contains \(N\) integers \(S_1, S_2, \ldots, S_N\) representing the test scores of each student, separated by spaces.
  • In the following \(Q\) lines, the \(i\)-th line \((1 \leq i \leq Q)\) contains integers \(a_i\) and \(b_i\) representing the student numbers of the two students to compare in the \(i\)-th question, separated by a space.

【输出】

Output \(Q\) lines. On the \(i\)-th line \((1 \leq i \leq Q)\), output Yes if \(S_{a_i} > S_{b_i}\), and No otherwise, as the answer to the \(i\)-th question.

【输入样例】

3 4
80 65 80
1 2
2 1
1 3
3 1

【输出样例】

Yes
No
No
No

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, q;  // n: 序列长度,q: 查询次数
int s[N];  // s[i]: 第i个元素的值

int main()
{
    cin >> n >> q;  // 读入序列长度和查询次数
    
    for (int i = 1; i <= n; i++)
    {
        cin >> s[i];  // 读入序列的每个元素
    }
    
    while (q--)  // 处理每个查询
    {
        int a, b;
        cin >> a >> b;  // 读入两个下标a和b
        
        if (s[a] > s[b])  // 比较s[a]和s[b]的大小
        {
            cout << "Yes" << endl;  // 如果s[a] > s[b],输出"Yes"
        }
        else
        {
            cout << "No" << endl;  // 如果s[a] ≤ s[b],输出"No"
        }
    }
    
    return 0;
}

【运行结果】

3 4
80 65 80
1 2
Yes
2 1
No
1 3
No
3 1
No

B - Spread of Rumors

【题目来源】

AtCoder:B - Spread of Rumors

【题目描述】

A school has \(N\) students, each assigned a student ID number from \(1\) to \(N\).
一所学校有 \(N\) 名学生,每名学生被分配了一个从 \(1\)\(N\) 的学生 ID 号。

At some point, an interesting rumor started. At the initial time (before any group work takes place), only the \(K\) students with student ID numbers \(1, 2, \ldots, K\) know this rumor, and no other students know it.
某个时候,一个有趣的谣言开始传播。在初始时刻(在任何小组活动发生之前),只有学号 \(1, 2, \ldots, K\)\(K\) 名学生知道这个谣言,其他学生都不知道。

From now on, \(M\) group work sessions will take place at this school, in order from the \(1\)-st to the \(M\)-th. Note that the same pair may be paired together again in different group work sessions.
从现在开始,这所学校将依次进行 \(M\) 次小组活动,从第 \(1\) 次到第 \(M\) 次。注意,同一对学生可能在不同的组队活动中再次配对。

In the \(i\)-th \((1 \leq i \leq M)\) group work session, the student with student ID \(A_i\) and the student with student ID \(B_i\) form a pair and work together. If at least one of the two paired students knows the rumor at the start of that group work session, then both students will know the rumor after that group work session ends. If neither of them knows the rumor, nothing changes.
在第 \(i\) 次(\(1 \leq i \leq M\))组队活动中,学号为 \(A_i\) 的学生和学号为 \(B_i\) 的学生组成一对并一起工作。如果在本次组队活动开始时,配对的两名学生中至少有一人知道这个谣言,那么在该次组队活动结束后,两名学生都会知道这个谣言。如果两人都不知道这个谣言,则没有变化。

The propagation of the rumor caused by a group work session affects all subsequent group work sessions.
由一次组队活动引起的谣言传播会影响所有后续的组队活动。

Determine the number of students who know the rumor after all group work sessions have been completed.
确定在所有组队活动完成后,知道这个谣言的学生人数。

【输入】

\(N\) \(M\) \(K\)
\(A_1\) \(B_1\)
\(A_2\) \(B_2\)
\(\vdots\)
\(A_M\) \(B_M\)

  • The first line contains \(N\) representing the number of students, \(M\) representing the number of group work sessions, and \(K\) representing the number of students who initially know the rumor, separated by spaces.
  • From the 2nd line to the \((M + 1)\)-th line, the student ID numbers of the students who form a pair in each group work session are given. If \(M = 0\), this part does not exist.
  • The \((1 + i)\)-th line \((1 \leq i \leq M)\) contains the student ID numbers \(A_i\) and \(B_i\) of the students who form a pair in the \(i\)-th group work session, separated by a space.

【输出】

Print in one line the number of students who know the rumor after all group work sessions have been completed.

【输入样例】

5 3 1
1 2
2 3
4 5

【输出样例】

3

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, m, k, ans;  // n: 总人数,m: 关系对数,k: 初始感染者数量,ans: 最终感染人数
int p[N];  // p[i]: 表示第i个人是否被感染,1表示感染,0表示未感染

int main()
{
    cin >> n >> m >> k;  // 读入总人数、关系对数、初始感染者数量
    
    for (int i = 1; i <= k; i++)  // 标记初始感染者
    {
        p[i] = 1;  // 前k个人是初始感染者
    }
    
    while (m--)  // 处理m对关系
    {
        int a, b;
        cin >> a >> b;  // 读入有关系的一对人
        
        // 如果a和b中至少有一人被感染
        if (p[a] == 1 || p[b] == 1)
        {
            p[a] = p[b] = 1;  // 两人都被感染
        }
    }
    
    for (int i = 1; i <= n; i++)  // 统计最终感染人数
    {
        ans += p[i];
    }
    
    cout << ans << endl;  // 输出最终感染人数
    return 0;
}

【运行结果】

5 3 1
1 2
2 3
4 5
3

C - Unique Seats

【题目来源】

AtCoder:C - Unique Seats

【题目描述】

Takahashi is managing a seating chart with \(H\) rows and \(W\) columns. The seat at row \(i\) and column \(j\) of the seating chart is called seat \((i, j)\). Each seat is assigned a group name represented by a single lowercase letter, and the group name of seat \((i, j)\) is denoted \(G_{i,j}\).
高桥正在管理一个座位表,它有 \(H\) 行和 \(W\) 列。座位表中第 \(i\) 行、第 \(j\) 列的座位称为座位 \((i, j)\)。每个座位被分配了一个由单个小写字母表示的组名,座位 \((i, j)\) 的组名记为 \(G_{i,j}\)

Takahashi wants to find all "unique seats" in the seating chart. A seat \((i, j)\) is a "unique seat" if and only if it satisfies both of the following conditions simultaneously:
高桥希望找出座位表中的所有"独特座位"。一个座位 \((i, j)\) 是"独特座位",当且仅当它同时满足以下两个条件:

  • Uniqueness in the row: Among the \(W\) seats in row \(i\), seat \((i, j)\) is the only one with group name \(G_{i,j}\). That is, the only \(k\) \((1 \leq k \leq W)\) satisfying \(G_{i,k} = G_{i,j}\) is \(k = j\).
    在行中唯一:在第 \(i\) 行的 \(W\) 个座位中,座位 \((i, j)\) 是唯一一个组名为 \(G_{i,j}\) 的座位。也就是说,满足 \(G_{i,k} = G_{i,j}\) 的唯一 \(k\)\(1 \leq k \leq W\))是 \(k = j\)
  • Uniqueness in the column: Among the \(H\) seats in column \(j\), seat \((i, j)\) is the only one with group name \(G_{i,j}\). That is, the only \(k\) \((1 \leq k \leq H)\) satisfying \(G_{k,j} = G_{i,j}\) is \(k = i\).
    在列中唯一:在第 \(j\) 列的 \(H\) 个座位中,座位 \((i, j)\) 是唯一一个组名为 \(G_{i,j}\) 的座位。也就是说,满足 \(G_{k,j} = G_{i,j}\) 的唯一 \(k\)\(1 \leq k \leq H\))是 \(k = i\)

Takahashi wants to read the group names of all unique seats in order of increasing row number, and within the same row in order of increasing column number, and concatenate them into a single string.
高桥希望按行号递增的顺序,同一行内按列号递增的顺序,读取所有独特座位的组名,并将它们连接成一个字符串。

Given the seating chart information, determine the above string. If no unique seats exist, determine the empty string.
给定座位表信息,确定上述字符串。如果没有独特座位,则确定为空字符串。

【输入】

\(H\) \(W\)
\(G_{1,1}G_{1,2}\cdots G_{1,W}\)
\(G_{2,1}G_{2,2}\cdots G_{2,W}\)
\(\vdots\)
\(G_{H,1}G_{H,2}\cdots G_{H,W}\)

  • The first line contains the number of rows \(H\) and the number of columns \(W\) of the seating chart, separated by a space.
  • The following \(H\) lines give the information for each row of the seating chart. The \(i\)-th \((1 \leq i \leq H)\) of these lines contains a string of \(W\) characters \(G_{i,1}G_{i,2}\cdots G_{i,W}\), which is the concatenation of the group names of the seats in row \(i\).

【输出】

Output in a single line the string obtained by concatenating the group names of the unique seats in order of increasing row number, and within the same row in order of increasing column number. If no unique seats exist, output the empty string (that is, output an empty line).

【输入样例】

3 3
abc
bca
cab

【输出样例】

abcbcacab

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 2005;
int n, m;  // n: 行数,m: 列数
char g[N][N];  // 字符矩阵
int row[N][130], col[N][130];  // row[i][c]: 第i行字符c的计数,col[j][c]: 第j列字符c的计数

int main()
{
    cin >> n >> m;  // 读入矩阵大小
    
    // 读入字符矩阵
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> g[i][j];
        }
    }
    
    // 统计每行每列中每个字符出现的次数
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            char c = g[i][j];  // 当前字符
            row[i][c]++;  // 第i行中字符c的计数加1
            col[j][c]++;  // 第j列中字符c的计数加1
        }
    }
    
    // 遍历矩阵中的每个字符
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            char c = g[i][j];  // 当前字符
            // 如果当前字符在第i行和第j列中都只出现1次
            if (row[i][c] == 1 && col[j][c] == 1)
            {
                s += g[i][j];  // 将字符加入结果字符串
            }
        }
    }
    
    cout << s << endl;  // 输出结果
    return 0;
}

【运行结果】

3 3
abc
bca
cab
abcbcacab

D - Highlighting with a Fluorescent Pen

【题目来源】

AtCoder:D - Highlighting with a Fluorescent Pen

【题目描述】

Takahashi is highlighting important parts of his textbook with a fluorescent marker while studying for exams.
高桥正在为考试复习,用荧光笔标记教科书中的重要部分。

Consider a particular line in the textbook. This line contains \(N\) characters arranged in a horizontal row, numbered from left to right as positions \(1, 2, \ldots, N\).
考虑教科书中的某一行。这一行包含 \(N\) 个字符,从左到右水平排列,编号为位置 \(1, 2, \ldots, N\)

The fluorescent marker Takahashi uses marks \(W\) consecutive characters each time it is used. Takahashi used this fluorescent marker a total of \(K\) times. In the \(i\)-th marking \((1 \leq i \leq K)\), he chose a starting position \(L_i\) and marked the \(W\) consecutive characters from position \(L_i\) to position \(L_i + W - 1\). The marking range never extends beyond the line (that is, \(1 \leq L_i \leq N - W + 1\) holds).
高桥使用的荧光笔每次标记 \(W\) 个连续的字符。高桥总共使用了 \(K\) 次这支荧光笔。在第 \(i\) 次标记(\(1 \leq i \leq K\))中,他选择了一个起始位置 \(L_i\),并标记了从位置 \(L_i\) 到位置 \(L_i + W - 1\)\(W\) 个连续字符。标记范围永远不会超出该行(即 \(1 \leq L_i \leq N - W + 1\) 成立)。

The same starting position may be chosen in different markings. Also, even if starting positions differ, their marking ranges may overlap. The number of times a character at each position is marked is the total number of marking operations that include that position.
在不同标记中可以选择相同的起始位置。此外,即使起始位置不同,它们的标记范围也可能重叠。每个位置的字符被标记的次数是包含该位置的所有标记操作的总次数。

After all marking operations are completed, determine how many times the character at each position was marked in total.
在所有标记操作完成后,确定每个位置的字符总共被标记了多少次。

【输入】

\(N\) \(W\) \(K\)
\(L_1\)
\(L_2\)
\(\vdots\)
\(L_K\)

  • The first line contains the total number of characters \(N\), the number of characters marked at once by the fluorescent marker \(W\), and the number of markings \(K\), separated by spaces.
  • The \(i\)-th \((1 \leq i \leq K)\) of the following \(K\) lines contains the starting position \(L_i\) of the \(i\)-th marking.

【输出】

Output \(N\) integers separated by spaces on a single line. The \(j\)-th \((1 \leq j \leq N)\) integer represents the number of times the character at position \(j\) was marked.

【输入样例】

10 3 2
2
5

【输出样例】

0 1 1 1 1 1 1 0 0 0

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, w, k;  // n: 区间长度,w: 操作宽度,k: 操作次数
int a[N], sa[N];  // a: 差分数组,sa: 前缀和数组

int main()
{
    cin >> n >> w >> k;  // 读入区间长度、操作宽度、操作次数
    
    while (k--)  // 处理每个操作
    {
        int l; 
        cin >> l;  // 读入操作的起始位置
        a[l]++;  // 在位置l处加1
        a[l + w]--;  // 在位置l+w处减1
    }
    
    // 计算前缀和,得到每个位置的总操作次数
    for (int i = 1; i <= n; i++)
    {
        sa[i] = sa[i - 1] + a[i];
    }
    
    // 输出每个位置的操作次数
    for (int i = 1; i <= n; i++)
    {
        cout << sa[i] << " ";
    }
    cout << endl;
    
    return 0;
}

【运行结果】

10 3 2
2
5
0 1 1 1 1 1 1 0 0 0

E - Making Rope from Materials

【题目来源】

AtCoder:E - Making Rope from Materials

【题目描述】

Takahashi needs to make exactly one rope of exactly \(W\) centimeters in length.
高桥需要制作一根恰好为 \(W\) 厘米长的绳子。

Takahashi has \(N\) types of strings. The \(i\)-th type of string has a length of \(L_i\) centimeters, and he has \(C_i\) of them in stock. Different types of strings may have the same length.
高桥有 \(N\) 种线。第 \(i\) 种线的长度为 \(L_i\) 厘米,他有 \(C_i\) 条库存。不同类型的线可能具有相同的长度。

Takahashi will select one or more of these strings and connect them in a straight line without cutting them, keeping their original lengths, to make a rope. The length of the resulting rope equals the sum of the lengths of the selected strings (there is no length reduction due to knots). He may use multiple strings of the same type, but he can use at most \(C_i\) strings of the \(i\)-th type.
高桥将选择这些线中的一条或多条,将它们按直线连接而不进行切割,保持其原始长度,以制作一根绳子。所得绳子的长度等于所选线长度的总和(打结不会导致长度减少)。他可以使用同种类型的多条线,但第 \(i\) 种类型最多只能使用 \(C_i\) 条。

Takahashi wants to minimize the number of strings used while ensuring that the total length of the selected strings is exactly \(W\) centimeters.
高桥希望在确保所选线的总长度恰好为 \(W\) 厘米的前提下,最小化使用的线数。

If it is possible to make a rope of exactly \(W\) centimeters, find the minimum number of strings needed. If it is impossible to make a rope of exactly \(W\) centimeters regardless of how the strings are chosen, output \(-1\).
如果可能制作出恰好为 \(W\) 厘米的绳子,求所需的最少线数。如果无论如何选择线都无法制作出恰好为 \(W\) 厘米的绳子,则输出 \(-1\)

【输入】

\(N\) \(W\)
\(L_1\) \(C_1\)
\(L_2\) \(C_2\)
\(\vdots\)
\(L_N\) \(C_N\)

  • The first line contains \(N\), the number of types of strings, and \(W\), the desired length of the rope, separated by a space.
  • From the 2nd line to the \((N + 1)\)-th line, information about each string is given.
  • The \((1 + i)\)-th line contains the length \(L_i\) and the stock count \(C_i\) of the \(i\)-th type of string, separated by a space.

【输出】

Output in one line the minimum number of strings needed to make a rope of exactly \(W\) centimeters. If it is impossible to make the rope, output \(-1\).

【输入样例】

3 10
3 2
5 3
7 1

【输出样例】

2

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 10005, M = 50005;
int n, w;  // n: 物品种类数,w: 目标总长度
int a[N], b[N], cur;  // a: 拆分后的物品长度,b: 拆分后的物品数量,cur: 拆分后物品总数
int dp[M];  // dp[j]: 凑成长度j所需的最小物品数量

int main()
{
    cin >> n >> w;  // 读入物品种类数和目标长度
    
    for (int i = 1; i <= n; i++)  // 处理每种物品
    {
        int l, c;
        cin >> l >> c;  // 读入物品长度l和数量c
        
        // 二进制拆分:将数量c拆分为1,2,4,...的幂次
        for (int j = 1; j <= c; j *= 2)
        {
            a[++cur] = l * j;  // 长度为l*j
            b[cur] = j;  // 数量为j
            c -= j;  // 减去已拆分的部分
        }
        
        // 处理剩余部分
        if (c)
        {
            a[++cur] = c * l;  // 长度为l*c
            b[cur] = c;  // 数量为c
        }
    }
    
    // 初始化DP数组为无穷大
    memset(dp, 0x3f, sizeof(dp));
    dp[0] = 0;  // 凑成长度0需要0个物品
    
    // 01背包DP
    for (int i = 1; i <= cur; i++)  // 遍历每个拆分后的物品
    {
        for (int j = w; j >= a[i]; j--)  // 逆序遍历容量
        {
            // 状态转移:选择或不选择当前物品
            dp[j] = min(dp[j], dp[j - a[i]] + b[i]);
        }
    }
    
    // 输出结果
    if (dp[w] == 0x3f3f3f3f)  // 如果无法凑成长度w
    {
        cout << -1 << endl;
    }
    else
    {
        cout << dp[w] << endl;  // 输出最小物品数量
    }
    
    return 0;
}

【运行结果】

3 10
3 2
5 3
7 1
2
posted @ 2026-03-16 19:28  团爸讲算法  阅读(1)  评论(0)    收藏  举报