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

A - Organization the Bookshelf

【题目来源】

AtCoder:A - Organizing the Bookshelf (atcoder.jp)

【题目描述】

Takahashi works at a library. On a bookshelf in the library, \(N\) books are lined up in a row, and each book has a catalog number assigned to it. The catalog number of the \(i\)-th book from the left (\(1≤i≤N\)) is \(A_i\). Note that different books may have the same catalog number.
高桥在图书馆工作。图书馆的书架上有一排 \(N\) 本书,每本书都分配有一个书目编号。从左数第 \(i\) 本书(\(1 ≤ i ≤ N\))的书目编号为 \(A_i\)。注意,不同的书可能具有相同的书目编号。

Aoki asks, "I'm looking for the book with catalog number \(K\). Where is it?"
青木问道:"我正在寻找书目编号为 \(K\) 的书。它在哪里?"

Among the \(N\) books on the bookshelf, find the book whose catalog number is exactly \(K\). If a book with catalog number \(K\) exists, output the smallest position of such a book (counted from the left, 1-indexed). If no such book exists, output −1.
在书架上的 \(N\) 本书中,找到书目编号恰好为 \(K\) 的书。如果存在书目编号为 \(K\) 的书,输出这类书中位置最靠左的书的位置(从左计数,从 \(1\) 开始编号)。如果不存在这样的书,输出 -1

【输入】

\(N\) \(K\)

\(A_1\ A_2\dots A_N\)

  • The first line contains an integer \(N\) representing the number of books and an integer \(K\) representing the catalog number being searched for, separated by a space.
  • The second line contains integers \(A_1,A_2,…,A_N\) representing the catalog numbers of the books, separated by spaces.

【输出】

If a book with catalog number exactly \(K\) exists, output on a single line the smallest position of such a book (counted from the left, 1-indexed). If no such book exists, output −1.

【输入样例】

5 3
1 4 3 2 3

【输出样例】

3

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int n, k;  // n: 序列长度,k: 要查找的数

int main()
{
    cin >> n >> k;  // 读入序列长度和要查找的数
    int pos = 1;  // 当前位置,从1开始计数
    
    for (int i = 1; i <= n; i++)
    {
        int x; 
        cin >> x;  // 读入当前数
        
        if (x == k)  // 如果找到目标数
        {
            cout << pos << endl;  // 输出当前位置
            return 0;  // 结束程序
        }
        pos++;  // 当前位置加1
    }
    
    // 如果循环结束后仍然没有找到
    if (pos == n + 1)  // 等价于 i==n+1
    {
        cout << -1 << endl;  // 输出-1表示未找到
    }
    return 0;
}

【运行结果】

5 3
1 4 3 2 3
3

B - Fruit Sorting

【题目来源】

AtCoder:B - Fruit Sorting (atcoder.jp)

【题目描述】

Takahashi is in charge of shipping fruits harvested at a farm.
高桥负责运输农场收获的水果。

\(N\) fruits have been harvested at the farm, each numbered from \(1\) to \(N\). For each fruit \(i\) \((1 \leq i \leq N)\), a sweetness level \(A_i\) has been measured; the higher this value, the sweeter and more delicious the fruit.
农场收获了 \(N\) 个水果,每个水果编号从 \(1\)\(N\)。对于每个水果 \(i\)\(1 ≤ i ≤ N\)),已测量其甜度水平 \(A_i\);该值越高,水果越甜、越美味。

It was discovered that \(M\) fruits have bruises. The numbers of the bruised fruits are given as \(B_1, B_2, \ldots, B_M\) (the order has no special meaning).
发现有 \(M\) 个水果存在碰伤。碰伤水果的编号依次为 \(B_1, B_2, …, B_M\)(顺序无特殊含义)。

Normally, bruised fruits are shipped as substandard products through a separate route from the regular one. However, fruits with a sweetness level of \(K\) or higher (i.e., \(A_i \geq K\)) are treated specially as premium products, so even if they have bruises, they are not classified as substandard and are included in the regular shipping route.
通常,碰伤水果会通过独立于常规路线的特殊路径作为次品运输。然而,甜度水平为 \(K\) 或以上(即 \(A_i ≥ K\))的水果被特别视为优质产品,因此即使存在碰伤,也不会被归类为次品,而是包含在常规运输路线中。

In summary, fruits that have bruises and have a sweetness level less than \(K\) are shipped as substandard products.
总之,存在碰伤且甜度水平小于 \(K\) 的水果将作为次品运输。

Find the number of fruits that Takahashi should ultimately ship as substandard products, and the total sweetness level of those fruits.
求高桥最终应作为次品运输的水果数量,以及这些水果的总甜度水平。

【输入】

\(N\) \(M\) \(K\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)
\(B_1\) \(B_2\) \(\ldots\) \(B_M\)

  • The first line contains \(N\) representing the total number of fruits, \(M\) representing the number of bruised fruits, and \(K\) representing the sweetness threshold for premium classification, separated by spaces.
  • The second line contains the sweetness levels of each fruit \(A_1, A_2, \ldots, A_N\), separated by spaces.
  • \(A_i\) represents the sweetness level of fruit \(i\).
  • The third line contains the numbers of the bruised fruits \(B_1, B_2, \ldots, B_M\), separated by spaces.
  • \(B_j\) represents the number of a bruised fruit.

【输出】

Print the number of fruits to be shipped as substandard products and the total sweetness level of those fruits, separated by a space, on a single line.

【输入样例】

5 3 10
8 12 5 15 7
1 3 4

【输出样例】

2 13

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 200005;
int n, m, k;  // n: 商品数量,m: 购买商品数量,k: 价格上限
int a[N], cnt, ans;  // a: 商品价格数组,cnt: 计数,ans: 总价

signed main()
{
    cin >> n >> m >> k;  // 读入商品数量,购买商品数量,价格上限
    
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];  // 读入每个商品的价格
    }
    
    for (int i = 1; i <= m; i++)
    {
        int x; 
        cin >> x;  // 读入要购买的商品编号
        if (a[x] < k)  // 如果商品价格小于上限k
        {
            cnt++;  // 计数器加1
            ans += a[x];  // 累加价格
        }
    }
    
    // 输出:购买的商品数量和总价
    cout << cnt << " " << ans << endl;
    
    return 0;
}

【运行结果】

5 3 10
8 12 5 15 7
1 3 4
2 13

C - Observing Plant Growth

【题目来源】

AtCoder:C - Observing Plant Growth (atcoder.jp)

【题目描述】

Takahashi is conducting an experiment growing \(N\) types of plants in his school science class.
高桥正在学校的科学课上开展种植 \(N\) 种植物的实验。

Each plant has a different initial height and daily growth rate. Specifically, the \(i\)-th plant (\(1 \leq i \leq N\)) has a height of \(A_i\) cm at the start of the experiment (day \(0\)) and grows by \(B_i\) cm per day. That is, the height of the \(i\)-th plant on day \(d\) (\(d = 0, 1, 2, \ldots\)) is \(A_i + B_i \times d\) cm.
每种植物具有不同的初始高度和日生长速率。具体而言,第 \(i\) 株植物(\(1 ≤ i ≤ N\))在实验开始时(第 \(0\) 天)的高度为 \(A_i\) 厘米,且每天生长 \(B_i\) 厘米。也就是说,第 \(i\) 株植物在第 \(d\) 天(\(d = 0, 1, 2, …\))的高度为 \(A_i + B_i × d\) 厘米。

Takahashi plans to check the heights of the plants every day on day \(0\), day \(1\), day \(2\), \(\ldots\), and end the observation on the first day when all plants have a height of at least \(M\) cm.
高桥计划在第 \(0\) 天、第 \(1\) 天、第 \(2\) 天……每天检查植物的高度,并在所有植物的高度都至少达到 \(M\) 厘米的第一天结束观察。

Find the day when the observation ends, that is, the smallest non-negative integer \(d\) such that \(A_i + B_i \times d \geq M\) holds for all \(i\) (\(1 \leq i \leq N\)).
求观察结束的天数,即满足对于所有 \(i\)\(1 ≤ i ≤ N\))都有 \(A_i + B_i × d ≥ M\) 的最小非负整数 \(d\)

Note that under the given constraints, the answer is guaranteed to exist as a finite value.
注意,在给定的约束条件下,答案保证存在且为有限值。

【输入】

\(N\) \(M\)
\(A_1\) \(B_1\)
\(A_2\) \(B_2\)
\(\vdots\)
\(A_N\) \(B_N\)

  • The first line contains an integer \(N\) representing the number of plant types and an integer \(M\) representing the target height, separated by a space.
  • The following \(N\) lines each contain, for the \(i\)-th line (\(1 \leq i \leq N\)), the initial height \(A_i\) and the daily growth rate \(B_i\) of the \(i\)-th plant, separated by a space.

【输出】

Print on a single line the smallest non-negative integer \(d\) such that all plants have a height of at least \(M\) cm.

【输入样例】

3 10
2 3
5 2
8 1

【输出样例】

3

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;

const int N = 200005;
int n, m, ans;  // n: 商品种类数,m: 目标数量,ans: 最大天数

int main()
{
    cin >> n >> m;  // 读入商品种类数和目标数量
    
    for (int i = 1; i <= n; i++)
    {
        int a, b;  // a: 初始数量,b: 每天新增数量
        cin >> a >> b;  // 读入每种商品的初始数量和每天新增数量
        
        // 计算收集m个该商品所需的天数
        // 公式: (m-a+(b-1))/b
        // 解释: 先减去已有的a个,然后计算需要的天数
        // 向上取整的技巧: (x + (b-1)) / b
        ans = max(ans, (m - a + (b - 1)) / b);
    }
    
    cout << ans << endl;  // 输出收集m个任意商品所需的最大天数
    return 0;
}

【运行结果】

3 10
2 3
5 2
8 1
3

D - Keys and Treasure Boxes

【题目来源】

AtCoder:D - Keys and Treasure Boxes (atcoder.jp)

【题目描述】

After a long adventure, Takahashi has reached ruins containing \(N\) treasure chests.
经过漫长的冒险,高桥抵达了藏有 \(N\) 个宝箱的遗迹。

Each treasure chest \(i\) (\(1 \leq i \leq N\)) is secured with a lock of strength \(C_i\). A larger strength value means a sturdier lock. All treasure chests have mutually distinct lock strengths.
每个宝箱 \(i\)\(1 ≤ i ≤ N\))都配有一把强度为 \(C_i\) 的锁。强度值越大,意味着锁越坚固。所有宝箱的锁强度互不相同。

Takahashi has \(M\) keys. Each key \(j\) (\(1 \leq j \leq M\)) has an unlocking power \(R_j\). Key \(j\) can open treasure chest \(i\) only if the key's unlocking power is at least as large as the lock's strength, that is, when \(C_i \leq R_j\). Note that different keys may have the same unlocking power.
高桥拥有 \(M\) 把钥匙。每把钥匙 \(j\)\(1 ≤ j ≤ M\))具有开启能力 \(R_j\)。钥匙 \(j\) 仅当开启能力至少与锁的强度一样大时才能打开宝箱 \(i\),即当 \(C_i ≤ R_j\) 时。注意,不同的钥匙可能具有相同的开启能力。

Takahashi selects some treasure chests he wants to open (possibly \(0\)), and assigns exactly one key to each selected treasure chest to open it. However, the same key cannot be assigned to two or more treasure chests. Additionally, the key assigned to each treasure chest must be able to open it (\(C_i \leq R_j\)). It is fine to leave some keys unused or some treasure chests unopened.
高桥选择一些他想要打开的宝箱(可能为 \(0\) 个),并为每个被选中的宝箱分配恰好一把钥匙来打开它。然而,同一把钥匙不能被分配给两个或更多宝箱。此外,分配给每个宝箱的钥匙必须能够打开它(\(C_i ≤ R_j\))。可以留一些钥匙不使用,也可以留一些宝箱不打开。

Find the maximum number of treasure chests Takahashi can open.
求高桥能够打开的最大宝箱数量。

【输入】

\(N\) \(M\)
\(C_1\) \(C_2\) \(\ldots\) \(C_N\)
\(R_1\) \(R_2\) \(\ldots\) \(R_M\)

  • The first line contains an integer \(N\) representing the number of treasure chests and an integer \(M\) representing the number of keys, separated by a space.
  • The second line contains integers \(C_1, C_2, \ldots, C_N\) representing the lock strengths of the treasure chests, separated by spaces.
  • The third line contains integers \(R_1, R_2, \ldots, R_M\) representing the unlocking powers of the keys, separated by spaces.

【输出】

Print the maximum number of treasure chests Takahashi can open, on a single line.

【输入样例】

3 3
10 20 30
15 25 35

【输出样例】

3

【解题思路】

image

【代码详解】

#include <bits++.h>
using namespace std;

const int N = 200005;
int n, m;  // n: 商品数量,m: 优惠券数量
int c[N], r[N];  // c: 商品价格数组,r: 优惠券金额数组

int main()
{
    cin >> n >> m;  // 读入商品数量和优惠券数量
    
    for (int i = 1; i <= n; i++)
    {
        cin >> c[i];  // 读入商品价格
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> r[i];  // 读入优惠券金额
    }
    
    // 对商品价格和优惠券金额进行排序
    sort(c + 1, c + n + 1);
    sort(r + 1, r + m + 1);
    
    int cnt = 0;  // 计数器,记录有多少商品可以使用优惠券
    // 双指针贪心匹配
    for (int i = 1, j = 1; i <= n; i++)
    {
        // 跳过所有金额小于当前商品价格的优惠券
        while (j <= m && r[j] < c[i])
        {
            j++;
        }
        // 如果还有可用的优惠券
        if (j <= m)
        {
            j++;  // 使用当前优惠券
            cnt++;  // 成功匹配一个商品
        }
    }
    
    cout << cnt << endl;  // 输出能使用优惠券的商品数量
    return 0;
}

【运行结果】

3 3
10 20 30
15 25 35
3

E - Assortment of Sweets

【题目来源】

AtCoder:E - Assortment of Sweets (atcoder.jp)

【题目描述】

Takahashi found \(N\) kinds of sweets at a candy shop. The price of the \(i\)-th \((1 \leq i \leq N)\) sweet is \(A_i\) yen. Since there is only one of each sweet in stock, for each sweet he must choose either "buy" or "don't buy." Note that different kinds of sweets may have the same price, but they are still distinguished as different sweets.
高桥在一家糖果店发现了 \(N\) 种糖果。第 \(i\) 种糖果(\(1 ≤ i ≤ N\))的价格为 \(A_i\) 日元。由于每种糖果仅有一个库存,他必须为每种糖果选择"购买"或"不购买"。注意,不同种类的糖果可能价格相同,但它们仍被视为不同的糖果。

Takahashi has exactly \(S\) yen. Since he wants to make the most of it, he would like to buy sweets that cost exactly \(S\) yen in total, without leaving any money.
高桥恰好有 \(S\) 日元。由于他希望充分利用这笔钱,他想购买总价恰好为 \(S\) 日元的糖果,不留下任何余额。

Among all ways to select \(0\) or more sweets from the \(N\) kinds, find the number of ways such that the total price of the selected sweets is exactly \(S\) yen. Note that if no sweets are selected, the total price is considered to be \(0\) yen.
在从 \(N\) 种糖果中选择 \(0\) 种或更多种的所有方式中,求使得所选糖果总价恰好为 \(S\) 日元的方式数。注意,如果未选择任何糖果,总价被视为 \(0\) 日元。

【输入】

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

  • The first line contains an integer \(N\) representing the number of kinds of sweets and an integer \(S\) representing the amount of money Takahashi has, separated by a space.
  • The second line contains integers \(A_1, A_2, \ldots, A_N\) representing the price of each sweet, separated by spaces.

【输出】

Print in one line the number of ways to select sweets such that the total price of the selected sweets is exactly \(S\) yen.

【输入样例】

4 10
2 3 5 7

【输出样例】

2

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1000005;
ll n, s;  // n: 糖果种类数,s: 目标总价
ll a[N];  // 糖果价格数组
unordered_map<ll, ll> l, r;  // 左右两部分的子集和及其出现次数

// 深度优先搜索枚举子集
void dfs(int pos, int end, ll sum, int type)
{
	if (pos > end)  // 如果已经处理完所有元素
	{
		if (sum > s)  // 如果当前和大于目标值,剪枝
		{
			return;
		}
		if (type == 1)  // 如果是左半部分
		{
			l[sum]++;  // 记录左半部分的子集和
		}
		else  // 如果是右半部分
		{
			r[sum]++;  // 记录右半部分的子集和
		}
		return;
	}
	// 两种选择:不选当前元素
	dfs(pos + 1, end, sum, type);
	// 选当前元素
	dfs(pos + 1, end, sum + a[pos], type);
}

int main()
{
    cin >> n >> s;  // 读入糖果种类数和目标总价
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];  // 读入每种糖果的价格
    }

    int mid = n / 2;  // 将数组分为两半
    // 枚举左半部分的所有子集
    dfs(1, mid, 0, 1);
    // 枚举右半部分的所有子集
    dfs(mid + 1, n, 0, 2);

    ll ans = 0;  // 方案总数
    // 遍历左半部分的子集和
    for (auto &c : l)
    {
        ll left_sum = c.first, left_cnt = c.second;  // 左子集和及其出现次数
        // 如果在右半部分存在右子集和 = s - left_sum
        if (r[s - left_sum])
        {
            // 方案数相乘累加
            ans += left_cnt * r[s - left_sum];
        }
    }
    cout << ans << endl;  // 输出凑出目标总价s的方案数
    return 0;
}

【运行结果】

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