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

A - Applause for the Successful Candidates

【题目来源】

AtCoder:A - Applause for the Successful Candidates

【题目描述】

Takahashi is in charge of the award ceremony as a staff member of a programming contest.
高桥作为编程竞赛的工作人员,负责颁奖典礼。

There are \(N\) participants in this contest, and the final score of the \(i\)-th participant is \(P_i\) points.
本次竞赛有 \(N\) 名参赛者,第 \(i\) 名参赛者的最终得分为 \(P_i\) 分。

Takahashi decided to award all participants whose final score is \(K\) points or more. During the ceremony, Takahashi claps for each awarded participant a number of times equal to that participant's final score. For example, he claps \(80\) times for a participant whose final score is \(80\) points.
高桥决定向所有最终得分不低于 \(K\) 分的参赛者颁奖。在颁奖典礼上,高桥为每位获奖的参赛者鼓掌,鼓掌次数等于该参赛者的最终得分。例如,如果一名参赛者的最终得分为 80 分,则他鼓掌 80 次。

Find the total number of times Takahashi claps. If there are no participants to be awarded, the total is \(0\).
求高桥鼓掌的总次数。如果没有需要颁奖的参赛者,则总次数为 0。

【输入】

\(N\) \(K\)
\(P_1\) \(P_2\) \(\ldots\) \(P_N\)

  • The first line contains the number of participants \(N\) and the threshold score \(K\) for the award, separated by a space.
  • The second line contains the final scores \(P_1, P_2, \ldots, P_N\) of each participant, separated by spaces.
  • \(P_i\) represents the final score (in points) of the \(i\)-th participant.

【输出】

Print the total number of times Takahashi claps in one line.

【输入样例】

5 60
45 72 88 55 60

【输出样例】

220

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, k, ans;

int main()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        // 统计所有大于等于k的数的和
        if (x >= k)
        {
            ans += x;
        }
    }
    cout << ans << endl;
    return 0;
}

【运行结果】

5 60
45 72 88 55 60
220

B - Harvest Interval in the Orchard

【题目来源】

AtCoder:B - Harvest Interval in the Orchard

【题目描述】

Takahashi works as a manager of an orchard. In this orchard, there are \(N\) fruit trees lined up in a row, numbered Tree \(1\), Tree \(2\), \(\ldots\), Tree \(N\) from left to right. Tree \(i\) \((1 \leq i \leq N)\) bears exactly one fruit with a sweetness level of \(T_i\).
高桥经营着一座果园。在这座果园中,有 \(N\) 棵果树排成一行,从左到右编号为果树 \(1\)、果树 \(2\)、……、果树 \(N\)。果树 \(i\)\(1 \leq i \leq N\))恰好结有一个果实,其甜度为 \(T_i\)

Takahashi wants to harvest only the fruits that meet the shipping standard. A fruit meets the shipping standard if and only if its sweetness level is at least \(L\) and at most \(R\).
高桥只希望采摘符合出货标准的果实。一个果实符合出货标准,当且仅当其甜度不低于 \(L\) 且不超过 \(R\)

Takahashi plans to select a contiguous interval of consecutively numbered trees and harvest all the fruits within that interval. Specifically, he chooses integers \(l, r\) \((1 \leq l \leq r \leq N)\) and considers the interval consisting of Tree \(l\), Tree \(l+1\), \(\ldots\), Tree \(r\). If all fruits on the trees within this interval meet the shipping standard, the interval is called harvestable.
高桥计划选择一个编号连续的果树区间,并采摘该区间内的所有果实。具体来说,他选择整数 \(l, r\)\(1 \leq l \leq r \leq N\)),并考虑由果树 \(l\)、果树 \(l+1\)、……、果树 \(r\) 组成的区间。如果此区间内所有果树上的果实都符合出货标准,则该区间称为可采摘区间

Find the maximum number of trees \(r - l + 1\) contained in a harvestable interval. If no harvestable interval exists, output \(0\).
求可采摘区间中包含的最多果树数量 \(r - l + 1\)。如果不存在可采摘区间,则输出 \(0\)

【输入】

\(N\) \(L\) \(R\)
\(T_1\) \(T_2\) \(\ldots\) \(T_N\)

  • The first line contains the integer \(N\) representing the number of trees, the integer \(L\) representing the lower bound (inclusive) of the sweetness level for the shipping standard, and the integer \(R\) representing the upper bound (inclusive) of the sweetness level for the shipping standard, separated by spaces.
  • The second line contains the integers \(T_1, T_2, \ldots, T_N\) representing the sweetness levels of the fruits on each tree, separated by spaces.

【输出】

Output in one line the maximum number of trees contained in a harvestable interval. If no harvestable interval exists, output \(0\).

【输入样例】

5 10 20
15 12 18 25 14

【输出样例】

3

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;

int n, l, r, ans;
int t[N];  // 标记数组,1表示符合条件,0表示不符合

int main()
{
    cin >> n >> l >> r;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        // 检查甜度是否在 [l, r] 范围内
        if (x >= l && x <= r)
        {
            t[i] = 1;  // 标记为符合条件的树
        }
    }
    int cnt = 0;  // 当前连续符合条件的树的计数
    for (int i = 1; i <= n; i++)
    {
        if (t[i] == 1)
        {
            cnt++;
            ans = max(ans, cnt);  // 更新最大长度
        }
        else
        {
            cnt = 0;  // 遇到不符合条件的树,重置计数
        }
    }
    cout << ans << endl;
    return 0;
}

【运行结果】

5 10 20
15 12 18 25 14
3

C - Make-Up Exam

【题目来源】

AtCoder:C - Make-Up Exam

【题目描述】

Takahashi and Aoki are in the same class and competing based on their final exam results.
高桥和青木是同班同学,他们正在根据期末考试的成绩进行比较。

The final exam consists of \(N\) subjects, each with its own maximum score. The maximum score for the \(i\)-th subject is \(P_i\) points. The score for each subject is an integer between \(0\) and \(P_i\), inclusive.
期末考试包含 \(N\) 门科目,每门科目有各自的满分。第 \(i\) 门科目的满分为 \(P_i\) 分。每门科目的分数是 \(0\)\(P_i\) 之间的整数(包含端点)。

As a result of the exam, Takahashi scored \(A_i\) points and Aoki scored \(B_i\) points on the \(i\)-th subject.
考试结果显示,高桥在第 \(i\) 门科目上得了 \(A_i\) 分,青木得了 \(B_i\) 分。

Here, we define the score difference as the value obtained by subtracting Aoki's total score across all subjects from Takahashi's total score across all subjects. Takahashi wants to maximize this score difference.
这里,我们定义分数差为高桥在所有科目上的总分减去青木在所有科目上的总分。高桥希望最大化这个分数差。

Thanks to the teacher's arrangement, Takahashi can choose exactly \(1\) subject from the \(N\) subjects and retake that subject's exam. Takahashi's score on the retaken subject will be changed to any integer between \(0\) and that subject's maximum score, inclusive. The new score may be the same as the original score. Aoki's scores do not change.
由于老师的安排,高桥可以恰好\(N\) 门科目中选择 \(1\) 科目,并重新参加该科目的考试。高桥在重考科目中的分数可以更改为 \(0\) 到该科目满分之间的任意整数(包含端点)。新分数可以与原始分数相同。青木的分数保持不变。

When Takahashi optimally chooses the subject and sets his new score, find the maximum possible score difference after the retake. Note that this value may be negative.
当高桥最优地选择科目并设定他的新分数时,求重考后可能的最大分数差。注意,这个值可能为负数。

【输入】

\(N\)
\(P_1\) \(P_2\) \(\cdots\) \(P_N\)
\(A_1\) \(A_2\) \(\cdots\) \(A_N\)
\(B_1\) \(B_2\) \(\cdots\) \(B_N\)

  • The first line contains an integer \(N\) representing the number of subjects.
  • The second line contains \(N\) integers \(P_1, P_2, \ldots, P_N\) separated by spaces, representing the maximum score for each subject.
  • The third line contains \(N\) integers \(A_1, A_2, \ldots, A_N\) separated by spaces, representing Takahashi's score for each subject.
  • The fourth line contains \(N\) integers \(B_1, B_2, \ldots, B_N\) separated by spaces, representing Aoki's score for each subject.

【输出】

Print in one line the maximum possible score difference after the retake when Takahashi acts optimally.

【输入样例】

3
100 100 100
60 80 50
70 70 70

【输出样例】

30

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;

int n, p[N], a[N], b[N], t[N];
int sum1, sum2;  // sum1: a的总和, sum2: b的总和

signed main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> p[i];
    }

    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        t[i] = p[i] - a[i];  // 计算p[i] - a[i]的差值
        sum1 += a[i];  // 累加a数组的总和
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> b[i];
        sum2 += b[i];  // 累加b数组的总和
    }
    int diff = sum1 - sum2;  // 计算a总和与b总和的差值
    // 对差值数组从大到小排序
    sort(t + 1, t + n + 1, greater<int>());
    // 输出结果:总和差值加上最大的t值
    cout << diff + t[1] << endl;
    return 0;
}

【运行结果】

3
100 100 100
60 80 50
70 70 70
30

D - Course Enrollment Order

【题目来源】

AtCoder:D - Course Enrollment Order

【题目描述】

Takahashi is trying to take all \(N\) courses at his university.
高桥正在尝试修读他大学的所有 \(N\) 门课程。

The courses are numbered from \(1\) to \(N\), and each course is taken exactly once. Some courses have prerequisite courses, and in order to take such a course, all of its prerequisite courses must have been completed beforehand. A single course may have multiple prerequisites. Courses with no prerequisites can be taken from the beginning.
课程编号从 \(1\)\(N\),每门课程恰好修读一次。有些课程有先修课程,为了修读这样的课程,其所有先修课程必须已经完成。一门课程可能有多个先修课程。没有先修课程的课程可以从一开始就修读。

There are \(M\) prerequisite relationships given, each in the form: "In order to take course \(B_j\), course \(A_j\) must have been completed first."
给出了 \(M\) 个先修关系,每个关系形式如下:"为了修读课程 \(B_j\),必须先完成课程 \(A_j\)。"

Takahashi takes courses one at a time. At each step, among the courses he has not yet taken whose prerequisites have all been completed (these are called available courses), he selects the one with the smallest number and takes it.
高桥一次修读一门课程。在每一步,在所有尚未修读且其先修课程已全部完成的课程中(这些课程称为可选课程),他选择编号最小的那一门进行修读。

Output the order in which Takahashi takes all the courses.
输出高桥修读所有课程的顺序。

It is guaranteed that there are no contradictions in the prerequisite relationships (i.e., no cycles exist), and that it is always possible to take all courses. Furthermore, the above rule uniquely determines the order of enrollment.
保证先修关系中没有矛盾(即不存在循环),并且始终可以修完所有课程。此外,上述规则唯一确定了选课顺序

【输入】

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

  • The first line contains an integer \(N\) representing the number of courses and an integer \(M\) representing the number of prerequisite relationships, separated by a space.
  • The \(j\)-th of the following \(M\) lines \((1 \leq j \leq M)\) contains integers \(A_j\) and \(B_j\) separated by a space, indicating that course \(A_j\) must be completed before taking course \(B_j\).

【输出】

Output the order in which Takahashi takes the courses on a single line, separated by spaces. That is, output \(N\) integers arranged from left to right in the order they are taken.

【输入样例】

4 3
1 2
3 4
2 4

【输出样例】

1 2 3 4

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005, M = 200005;

int n, m;
// 优先队列(最小堆),用于实现字典序最小的拓扑排序
priority_queue<int, vector<int>, greater<int> > q;
// 存储拓扑排序的序列
vector<int> seq;
// 入度数组
int ind[N];
// 邻接表(数组模拟链表)
int h[N], e[M], ne[M], idx;

// 添加有向边 a -> b
void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int main()
{
    cin >> n >> m;
    // 初始化邻接表头指针
    memset(h, -1, sizeof(h));
    for (int i = 1; i <= m; i++)
    {
        int a, b;
        cin >> a >> b;
        add(a, b);
        // 增加终点 b 的入度
        ind[b]++;
    }

    // 将所有入度为 0 的顶点加入优先队列
    for (int i = 1; i <= n; i++)
    {
        if (ind[i] == 0)
        {
            q.push(i);
        }
    }

    while (!q.empty())
    {
        // 取出当前编号最小的入度为 0 的顶点
        int u = q.top();
        q.pop();
        // 将该顶点加入拓扑序列
        seq.push_back(u);
        
        // 遍历顶点 u 的所有出边
        for (int i = h[u]; i != -1; i = ne[i])
        {
            int j = e[i];
            // 减少后继顶点的入度
            ind[j]--;
            // 如果入度变为 0,则加入优先队列
            if (ind[j] == 0)
            {
                q.push(j);
            }
        }
    }

    // 输出拓扑排序的结果
    for (int i = 0; i < seq.size(); i++)
    {
        cout << seq[i] << " ";
    }
    cout << endl;
    return 0;
}

【运行结果】

4 3
1 2
3 4
2 4
1 2 3 4

E - Counting Subsequences

【题目来源】

AtCoder:E - Counting Subsequences

【题目描述】

Takahashi is researching algorithms related to sequences. Today, he is working on a subsequence matching problem in sequences.
高桥正在研究与序列相关的算法。今天,他正在研究序列中的子序列匹配问题。

You are given a sequence \(A = (A_1, A_2, \ldots, A_N)\) of length \(N\) and a pattern sequence \(P = (P_1, P_2, \ldots, P_K)\) of length \(K\). Each element of the sequence \(A\) and the pattern sequence \(P\) is a positive integer.
给定一个长度为 \(N\) 的序列 \(A = (A_1, A_2, \ldots, A_N)\) 和一个长度为 \(K\) 的模式序列 \(P = (P_1, P_2, \ldots, P_K)\)。序列 \(A\) 和模式序列 \(P\) 的每个元素都是正整数。

Takahashi wants to find the number of ways to choose \(K\) distinct positions from the sequence \(A\) such that the subsequence formed by those positions, preserving the original order, matches the pattern sequence \(P\).
高桥希望找出从序列 \(A\) 中选择 \(K\) 个不同位置的方法数,使得这些位置构成的子序列(保持原始顺序)与模式序列 \(P\) 匹配。

More precisely, find the number of index tuples \((i_1, i_2, \ldots, i_K)\) satisfying \(1 \leq i_1 < i_2 < \cdots < i_K \leq N\) such that \(A_{i_j} = P_j\) holds for all \(j\) \((1 \leq j \leq K)\).
更精确地说,求满足 \(1 \leq i_1 < i_2 < \cdots < i_K \leq N\) 的索引元组 \((i_1, i_2, \ldots, i_K)\) 的数量,使得对所有 \(j\)\(1 \leq j \leq K\))有 \(A_{i_j} = P_j\) 成立。

Note that if the chosen index tuples differ in even one position, they are counted as distinct selections, even if the values of all selected elements are the same.
注意,即使所选的所有元素的值相同,只要所选索引元组中有一个位置不同,它们就被计为不同的选择。

Since the answer can be very large, find it modulo \(10^9 + 7\).
由于答案可能非常大,请对 \(10^9 + 7\) 取模后输出结果。

【输入】

\(N\) \(K\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)
\(P_1\) \(P_2\) \(\ldots\) \(P_K\)

  • The first line contains two integers \(N\) and \(K\), separated by a space, representing the length of the sequence \(A\) and the length of the pattern sequence \(P\), respectively.
  • The second line contains the elements \(A_1, A_2, \ldots, A_N\) of the sequence \(A\), separated by spaces.
  • The third line contains the elements \(P_1, P_2, \ldots, P_K\) of the pattern sequence \(P\), separated by spaces.

【输出】

Print on a single line the number of index tuples satisfying the condition, modulo \(10^9 + 7\).

【输入样例】

5 2
1 2 1 2 1
1 2

【输出样例】

3

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 100005, M = 105, mod = 1e9 + 7;

int n, k;
// a 数组存储主序列
int a[N];
// p 数组存储要匹配的子序列
int p[M];
// dp[i][j] 表示:考虑主序列前 i 个元素,匹配到子序列前 j 个元素的方案数
int dp[N][M];

int main()
{
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= k; i++)
    {
        cin >> p[i];
    }

    // 初始化:主序列前 i 个元素匹配空子序列的方案数为 1
    for (int i = 0; i <= n; i++)
    {
        dp[i][0] = 1;
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= k; j++)
        {
            // 不选主序列第 i 个元素
            dp[i][j] = dp[i - 1][j];
            // 如果主序列第 i 个元素等于子序列第 j 个元素
            if (a[i] == p[j])
            {
                // 可以选择主序列第 i 个元素来匹配子序列第 j 个元素
                dp[i][j] = (dp[i][j] + dp[i - 1][j - 1]) % mod;
            }
        }
    }
    
    // 输出主序列前 n 个元素匹配到子序列前 k 个元素的方案数
    cout << dp[n][k] << endl;
    return 0;
}

【运行结果】

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