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

A - Number of Successful Applicants

【题目来源】

AtCoder:A - Number of Successful Applicants

【题目描述】

Takahashi has just finished grading the school's final exam. \(N\) students took this exam, and each student is assigned an attendance number from \(1\) to \(N\).
高桥刚刚批改完学校的期末考试。\(N\) 名学生参加了这次考试,每名学生被分配了一个从 \(1\)\(N\) 的出席编号。

According to the school's regulations, students who scored \(K\) points or more on the exam pass and are exempt from the makeup exam. Students who scored less than \(K\) points fail and must take the makeup exam.
根据学校规定,考试得分不低于 \(K\) 分的学生通过,免于补考。考试得分低于 \(K\) 分的学生未通过,必须参加补考。

The score of the student with attendance number \(i\) is \(S_i\) points.
出席编号为 \(i\) 的学生的得分为 \(S_i\) 分。

Takahashi wants to know the number of students who passed. Find the number of students who scored \(K\) points or more on the exam.
高桥想知道通过考试的学生人数。求考试得分不低于 \(K\) 分的学生人数。

【输入】

\(N\) \(K\)
\(S_1\) \(S_2\) \(\ldots\) \(S_N\)

  • The first line contains an integer \(N\) representing the number of students and an integer \(K\) representing the passing score threshold, separated by a space.
  • The second line contains integers \(S_1, S_2, \ldots, S_N\) representing each student's exam score, separated by spaces.

【输出】

Print the number of students who passed on a single line.

【输入样例】

5 60
72 45 60 88 59

【输出样例】

3

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, k, ans;  // n: 数字个数,k: 阈值,ans: 计数结果

int main()
{
    cin >> n >> k;  // 读入数字个数和阈值
    
    for (int i = 1; i <= n; i++)  // 遍历每个数字
    {
        int x; 
        cin >> x;  // 读入当前数字
        
        if (x >= k)  // 如果当前数字大于等于阈值k
        {
            ans++;  // 计数加1
        }
    }
    
    cout << ans << endl;  // 输出大于等于k的数字个数
    return 0;
}

【运行结果】

5 60
72 45 60 88 59
3

B - Cheerful Support Message

【题目来源】

AtCoder:B - Cheerful Support Message

【题目描述】

Takahashi set up a cheer message board at his school's cultural festival.
高桥在学校的文化节上设置了一个加油留言板。

On this board, visitors can write cheer messages for the performers. Takahashi wants to count the number of "energetic cheer messages" in order to analyze the excitement of the cultural festival.
在这个留言板上,参观者可以为表演者写下加油留言。高桥想要统计"充满活力的加油留言"的数量,以分析文化节的热烈程度。

An "energetic cheer message" is a message whose string contains \(K\) or more exclamation marks !.
一条"充满活力的加油留言"是指其字符串包含 \(K\) 个或更多感叹号 ! 的留言。

\(N\) visitors each wrote exactly one cheer message. Each visitor's message is given as a string consisting of lowercase English letters, uppercase English letters, digits, and exclamation marks. Determine how many "energetic cheer messages" there are.
\(N\) 名参观者每人恰好写了一条加油留言。每位参观者的留言以一个由小写英文字母、大写英文字母、数字和感叹号组成的字符串给出。确定有多少条"充满活力的加油留言"。

【输入】

\(N\) \(K\)
\(S_1\)
\(S_2\)
\(\vdots\)
\(S_N\)

The first line contains two integers separated by a space: \(N\), the number of visitors, and \(K\), the threshold number of exclamation marks for an "energetic cheer message".

For each of the following \(N\) lines, the \(i\)-th line (\(1 \leq i \leq N\)) contains a single string \(S_i\) representing the message of the \(i\)-th visitor.

【输出】

Print the number of "energetic cheer messages" on a single line.

【输入样例】

3 2
Hello!
Great!!Work!!
Nice

【输出样例】

1

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, k, ans;  // n: 字符串个数,k: 阈值,ans: 满足条件的字符串个数

int main()
{
    cin >> n >> k;  // 读入字符串个数和阈值
    
    for (int i = 1; i <= n; i++)  // 遍历每个字符串
    {
        string s; 
        cin >> s;  // 读入当前字符串
        
        int cnt = 0;  // 统计感叹号'!'出现的次数
        for (int j = 0; j < s.size(); j++)  // 遍历字符串的每个字符
        {
            if (s[j] == '!')  // 如果当前字符是感叹号
            {
                cnt++;  // 计数加1
            }
        }
        
        if (cnt >= k)  // 如果感叹号数量大于等于阈值k
        {
            ans++;  // 满足条件的字符串个数加1
        }
    }
    
    cout << ans << endl;  // 输出结果
    return 0;
}

【运行结果】

3 2
Hello!
Great!!Work!!
Nice
1

C - Consecutive Card Distribution

【题目来源】

AtCoder:C - Consecutive Card Distribution

【题目描述】

Takahashi is organizing a card game tournament.
高桥正在组织一场卡牌游戏比赛。

The tournament uses \(N\) cards. Card \(i\) (\(1 \leq i \leq N\)) has a positive integer \(A_i\) written on it, and all integers written on the \(N\) cards are distinct.
比赛使用 \(N\) 张卡牌。卡牌 \(i\)\(1 ≤ i ≤ N\))上写有一个正整数 \(A_i\),且写在 \(N\) 张卡牌上的所有整数互不相同。

Takahashi wants to divide all \(N\) cards into several groups. Each card must belong to exactly one group, and every group must contain at least one card. Furthermore, each group must be a "consecutive group" as defined below.
高桥希望将所有 \(N\) 张卡牌分成若干组。每张卡牌必须恰好属于一组,且每组必须至少包含一张卡牌。此外,每组必须是一个如下定义的"连续组"。

A set of cards is a consecutive group if the set of integers written on the cards in it can be expressed as \(\{a, a+1, a+2, \ldots, a+k-1\}\) for some integer \(a\) and positive integer \(k\). In other words, it is a set consisting of \(k\) consecutive integers. When \(k = 1\), i.e., a group consisting of just one card, it is also a consecutive group.
一组卡牌是一个连续组,如果写在卡牌上的整数集合可以表示为 \({a, a+1, a+2, …, a+k-1}\),其中 \(a\) 为某个整数,\(k\) 为正整数。换句话说,它是一个由 \(k\) 个连续整数组成的集合。当 \(k=1\) 时,即仅由一张卡牌组成的组,也是一个连续组。

For example, a set of \(3\) cards with the integers \(3, 5, 4\) written on them forms the integer set \(\{3, 4, 5\}\), which consists of \(3\) consecutive integers, so it is a consecutive group. On the other hand, a set of \(3\) cards with the integers \(2, 4, 5\) is not a consecutive group because \(3\) is missing between \(2\) and \(4\).
例如,一组写有整数 \(3, 5, 4\)\(3\) 张卡牌形成整数集合 \(\{3, 4, 5\}\),它由 \(3\) 个连续整数组成,因此是一个连续组。另一方面,一组写有整数 \(2, 4, 5\)\(3\) 张卡牌不是一个连续组,因为在 \(2\)\(4\) 之间缺少 \(3\)

When dividing all \(N\) cards into consecutive groups, find the minimum number of groups.
当将所有 \(N\) 张卡牌分成连续组时,求最少的组数。

【输入】

\(N\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)

  • The first line contains an integer \(N\) representing the number of cards.
  • The second line contains the positive integers \(A_1, A_2, \ldots, A_N\) written on each card, separated by spaces.

【输出】

Print in one line the minimum number of groups when dividing all \(N\) cards into consecutive groups.

【输入样例】

3
3 5 4

【输出样例】

1

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n;  // 数字个数
int a[N], ans;  // a: 存储数字的数组,ans: 结果

int main()
{
    cin >> n;  // 读入数字个数
    
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];  // 读入每个数字
    }
    
    sort(a + 1, a + n + 1);  // 对数字进行排序
    
    ans = 1;  // 初始至少有一个区间
    for (int i = 2; i <= n; i++)  // 从第二个数字开始遍历
    {
        if (a[i] != a[i - 1] + 1)  // 如果当前数字不是前一个数字加1
        {
            ans++;  // 新区间开始
        }
    }
    
    cout << ans << endl;  // 输出区间个数
    return 0;
}

【运行结果】

3
3 5 4
1

D - Conservation Plan for the Botanical Garden

【题目来源】

AtCoder:D - Conservation Plan for the Botanical Garden

【题目描述】

Takahashi is the manager of a botanical garden. The garden contains \(N\) plants, each numbered from \(1\) to \(N\).
高桥是一个植物园的园长。这个植物园里有 \(N\) 株植物,每株编号从 \(1\)\(N\)

Each plant \(i\) (\(1 \leq i \leq N\)) has an "ornamental value" \(A_i\) and a "drought resistance" \(B_i\). Plants with higher ornamental value are more attractive to visitors, and plants with higher drought resistance are more resilient to water shortages.
每株植物 \(i\)\(1 ≤ i ≤ N\))有一个"观赏价值" \(A_i\) 和一个"抗旱性" \(B_i\)。观赏价值越高的植物对游客越有吸引力,抗旱性越高的植物对缺水的适应能力越强。

An intense heatwave is expected this summer, and some plants may wither due to water shortage. Specifically, plants whose drought resistance \(B_i\) is at least the threshold \(T\) will survive without any intervention, but plants whose \(B_i\) is less than \(T\) will wither if no measures are taken.
预计今年夏天将有强烈的热浪,一些植物可能因缺水而枯萎。具体来说,抗旱性 \(B_i\) 不低于阈值 \(T\) 的植物无需任何干预即可存活,但 \(B_i\) 低于 \(T\) 的植物如果不采取措施就会枯萎。

To protect the plants that would wither, Takahashi has decided to install irrigation equipment on some plants. For each plant \(i\), he chooses whether or not to install irrigation equipment. Irrigation equipment can be installed on any plant (including plants whose drought resistance is at least \(T\)), and it is also allowed to install none at all. However, at most one irrigation equipment can be installed per plant. Installing irrigation equipment on plant \(i\) costs \(C_i\), and a plant with irrigation equipment installed will not wither regardless of its drought resistance value.
为了保护会枯萎的植物,高桥决定在一些植物上安装灌溉设备。对于每株植物 \(i\),他选择是否安装灌溉设备。灌溉设备可以安装在任何植物上(包括抗旱性不低于 \(T\) 的植物),也允许完全不安装。但是,每株植物最多只能安装一个灌溉设备。在植物 \(i\) 上安装灌溉设备的成本为 \(C_i\),安装了灌溉设备的植物无论其抗旱性如何都不会枯萎。

The total installation cost of the irrigation equipment must not exceed Takahashi's budget \(M\).
灌溉设备的总安装成本不得超过高桥的预算 \(M\)

In summary, plant \(i\) survives (does not wither) if it satisfies either (or both) of the following conditions:
总之,植物 \(i\) 在满足以下任一(或全部)条件时存活(不枯萎):

  • Irrigation equipment is installed on plant \(i\)
    在植物 i 上安装了灌溉设备。
  • Its drought resistance \(B_i\) is at least \(T\)
    其抗旱性 \(B_i\) 不低于 \(T\)

Plants that satisfy neither of these conditions will wither. Note that even if both conditions are satisfied simultaneously, the ornamental value is not counted twice.
不满足任一条件的植物将会枯萎。注意,即使同时满足两个条件,观赏价值也不会被重复计算。

Takahashi wants to maximize the total ornamental value of the surviving plants by choosing which plants to install irrigation equipment on, within the budget \(M\).
高桥希望在预算 \(M\) 内,通过选择在哪些植物上安装灌溉设备,来最大化存活植物的总观赏价值。

Find the maximum possible sum of ornamental values \(A_i\) over all surviving plants.
求所有存活植物的观赏价值 \(A_i\) 之和的最大可能值。

【输入】

\(N\) \(M\) \(T\)
\(A_1\) \(B_1\) \(C_1\)
\(A_2\) \(B_2\) \(C_2\)
\(\vdots\)
\(A_N\) \(B_N\) \(C_N\)

  • The first line contains the number of plants \(N\), Takahashi's budget \(M\), and the drought resistance threshold \(T\), separated by spaces.
  • The \(i\)-th of the following \(N\) lines contains the ornamental value \(A_i\), drought resistance \(B_i\), and irrigation equipment installation cost \(C_i\) of plant \(i\), separated by spaces.

【输出】

Output the maximum possible total ornamental value of the surviving plants on a single line.

【输入样例】

3 100 50
80 30 60
50 60 40
30 40 50

【输出样例】

130

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 105, M = 10005;
int n, m, t;  // n: 物品数量,m: 总容量限制,t: 阈值
int a[N], b[N], c[N];  // a[i]: 第i个物品的价值,b[i]: 第i个物品的属性,c[i]: 第i个物品的容量
int dp[N][M], ans;  // dp[i][j]: 考虑前i个物品,容量为j时的最大价值,ans: 答案

int main()
{
    cin >> n >> m >> t;  // 读入物品数量、总容量限制、阈值
    
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i] >> b[i] >> c[i];  // 读入每个物品的价值、属性、容量
    }
    
    // 动态规划
    for (int i = 1; i <= n; i++)  // 遍历每个物品
    {
        for (int j = 0; j <= m; j++)  // 遍历所有可能的容量
        {
            // 情况1:不选当前物品
            if (b[i] >= t)  // 如果当前物品的属性大于等于阈值t
            {
                dp[i][j] = dp[i - 1][j] + a[i];  // 获得这个物品的价值,不占用容量
            }
            else
            {
                dp[i][j] = dp[i - 1][j];  // 正常情况,不选则价值不变
            }
            
            // 情况2:选当前物品(需要容量足够)
            if (j >= c[i])  // 如果容量足够选择当前物品
            {
                // 取两种情况的最大值
                dp[i][j] = max(dp[i][j], dp[i - 1][j - c[i]] + a[i]);
            }
        }
    }
    
    // 寻找最大价值
    for (int j = 0; j <= m; j++)  // 遍历所有可能的容量
    {
        ans = max(ans, dp[n][j]);  // 取考虑所有物品后的最大价值
    }
    
    cout << ans << endl;  // 输出结果
    return 0;
}

【运行结果】

3 100 50
80 30 60
50 60 40
30 40 50
130

E - Loading Cargo

【题目来源】

AtCoder:E - Loading Cargo

【题目描述】

Takahashi is trying to stack cardboard boxes onto a truck bed for moving.
高桥正在尝试将纸箱堆叠到卡车车厢上以便搬运。

Takahashi has \(N\) cardboard boxes, where the \(i\)-th box has weight \(W_i\) and load capacity \(D_i\). He selects some of these boxes (possibly \(0\), but each box can be selected at most once) and stacks the selected boxes in a single column from bottom to top in any order he likes.
高桥有 \(N\) 个纸箱,其中第 \(i\) 个箱子的重量为 \(W_i\),承重能力为 \(D_i\)。他选择其中的一些箱子(可能为 \(0\) 个,但每个箱子最多只能被选择一次)并将选中的箱子按他喜欢的任意顺序从下到上堆叠成一列。

However, there is a load capacity constraint on the boxes. If the total weight of all boxes placed on top of a given box exceeds that box's load capacity (i.e., is strictly greater than the load capacity), that box will be crushed. If the total weight is at most the load capacity, the box will not be crushed. If even one box is crushed, the stacking is not valid.
但是,箱子存在承重能力限制。如果放置在一个给定箱子上方的所有箱子的总重量超过该箱子的承重能力(即严格大于承重能力),则该箱子会被压坏。如果总重量不超过承重能力,箱子就不会被压坏。即使只有一个箱子被压坏,该堆叠也是无效的。

Takahashi wants to select and stack boxes so that the stacking is valid. Maximize the number of boxes used in the stacking.
高桥希望选择和堆叠箱子,使得堆叠有效。最大化堆叠中使用的箱子数量。

More precisely: select a subset \(S\) from the \(N\) boxes (\(S\) may be empty). Stack the boxes in \(S\) in some order in a single column from bottom to top. The stacking is said to be valid if, for every box in \(S\), the total weight of all boxes above it is at most that box's load capacity. A subset \(S\) is said to be feasible if there exists at least one ordering of the boxes in \(S\) such that the stacking is valid. Find the maximum value of \(|S|\) among all feasible subsets \(S\).
更精确地说:从 \(N\) 个箱子中选择一个子集 \(S\)\(S\) 可以是空集)。将 \(S\) 中的箱子按某种顺序从下到上堆叠成一列。如果对于 \(S\) 中的每个箱子,其上方的所有箱子的总重量不超过该箱子的承重能力,则称该堆叠是有效的。如果至少存在一种 \(S\) 中箱子的排列顺序使得堆叠有效,则称子集 \(S\) 是可行的。求所有可行子集 \(S\)\(|S|\) 的最大值。

【输入】

\(N\)
\(W_1\) \(D_1\)
\(W_2\) \(D_2\)
\(\vdots\)
\(W_N\) \(D_N\)

  • The first line contains an integer \(N\), the number of cardboard boxes.
  • The next \(N\) lines give the information for each box.
  • The \((1 + i)\)-th line contains the weight \(W_i\) and load capacity \(D_i\) of the \(i\)-th box, separated by a space.

【输出】

Print on a single line the maximum value of \(|S|\) over all feasible subsets \(S\), that is, the maximum number of boxes that can be selected so that the stacking is valid.

【输入样例】

3
3 5
2 3
4 2

【输出样例】

2

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n;  // n: 箱子数量
struct Node
{
    int w, d;  // w: 箱子重量,d: 承重
}a[N];

// 比较函数:按 (重量 + 承重) 从小到大排序
// 即按 (d + w) 排序
bool cmp(Node x, Node y)
{
    return x.d + x.w < y.d + y.w;
}

priority_queue<int> pq;  // 最大堆,存储已选箱子的重量

signed main()
{
    cin >> n;  // 读入箱子数量
    
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].w >> a[i].d;  // 读入每个箱子的重量和承重
    }
    
    // 按 (重量 + 承重) 从小到大排序
    sort(a + 1, a + n + 1, cmp);
    
    int tot = 0;  // 当前已选箱子的总重量
    
    for (int i = 1; i <= n; i++)  // 遍历所有箱子
    {
        if (a[i].d >= tot)  // 如果当前箱子的承重大于等于所有叠放箱子的重量
        {
            pq.push(a[i].w);  // 将箱子加入堆
            tot += a[i].w;  // 增加总重量
        }
        else  // 否则
        {
            if (a[i].w < pq.top())  // 如果当前箱子的重量小于堆中最大箱子的重量
            {
                tot += (a[i].w - pq.top());  // 更新总重量
                pq.pop();  // 移除堆顶箱子
                pq.push(a[i].w);  // 加入当前箱子
            }
            // 否则,不选择当前箱子
        }
    }
    
    cout << pq.size() << endl;  // 输出最终能完成的箱子数量
    return 0;
}

【运行结果】

3
3 5
2 3
4 2
2
posted @ 2026-03-12 14:28  团爸讲算法  阅读(2)  评论(0)    收藏  举报