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

A - Equalizing Water

【题目来源】

AtCoder:A - Equalizing Water

【题目描述】

Takahashi manages a water system consisting of \(N\) tanks arranged in a horizontal row. The tanks are numbered from \(1\) to \(N\) from left to right, and tank \(i\) currently contains \(A_i\) liters of water.
高桥管理一个由 \(N\) 个水箱组成的水平排列的供水系统。水箱从左到右编号为 \(1\)\(N\),水箱 \(i\) 当前装有 \(A_i\) 升水。

To adjust the water levels in this system, Takahashi can perform the following operation any number of times (including zero times). The pair of tanks chosen can be different for each operation.
为了调整该系统内的水位,高桥可以执行以下操作任意多次(包括零次)。每次操作可以选择不同的相邻水箱对。

Operation: Choose two adjacent tanks \(i\) and \(i + 1\) (\(1 \leq i \leq N - 1\)), and transfer \(1\) liter of water from one tank to the other. Specifically, perform one of the following:
操作:选择两个相邻的水箱 \(i\)\(i+1\)\(1≤i≤N−1\)),并将 \(1\) 升水从一个水箱转移到另一个水箱。具体来说,执行以下操作之一:

  • Decrease the water in tank \(i\) by \(1\) liter and increase the water in tank \(i + 1\) by \(1\) liter.
    将水箱 \(i\) 的水量减少 \(1\) 升,并将水箱 \(i+1\) 的水量增加 \(1\) 升。
  • Decrease the water in tank \(i + 1\) by \(1\) liter and increase the water in tank \(i\) by \(1\) liter.
    将水箱 \(i+1\) 的水量减少 \(1\) 升,并将水箱 \(i\) 的水量增加 \(1\) 升。

However, the water level in each tank must remain \(0\) or more after every operation. That is, you cannot decrease the water in a tank that has \(0\) liters of water.
但是,每次操作后每个水箱的水位必须保持为 \(0\) 或以上。也就是说,不能减少水量为 \(0\) 升的水箱的水量。

Note that this operation does not change the total amount of water.
注意,此操作不会改变总水量。

Takahashi wants to make the water levels of all tanks equal by repeating operations. Determine whether this is achievable. If it is possible, output Yes; otherwise, output No.
高桥希望通过重复操作使所有水箱的水位相等。判断这是否可以实现。如果可能,输出 Yes;否则,输出 No

【输入】

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

  • The first line contains an integer \(N\), representing the number of tanks.
  • The second line contains \(N\) integers \(A_1, A_2, \ldots, A_N\) separated by spaces, representing the amount of water in each tank.

【输出】

If it is possible to make the water levels of all tanks equal, output Yes; otherwise, output No, in a single line.

【输入样例】

3
1 2 3

【输出样例】

Yes

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, sum;  // n: 数字个数,sum: 数字总和

signed main()
{
    cin >> n;  // 读入数字个数
    
    for (int i = 1; i <= n; i++)  // 遍历n个数字
    {
        int x; 
        cin >> x;  // 读入当前数字
        sum += x;  // 累加到总和
    }
    
    // 判断总和是否能被n整除
    if (sum % n == 0)  // 如果总和能被n整除
    {
        cout << "Yes" << endl;  // 输出Yes
    }
    else  // 否则
    {
        cout << "No" << endl;  // 输出No
    }
    
    return 0;
}

【运行结果】

3
1 2 3
Yes

B - Climbing to the Summit

【题目来源】

AtCoder:B - Climbing to the Summit

【题目描述】

Takahashi is climbing from the base of a mountain toward the summit.
高桥正从山脚向山顶攀登。

The trail from the base to the summit is divided into \(N\) sections, each with a difficulty rating representing the severity of the climb. The difficulty of the \(i\)-th section \((1 \leq i \leq N)\) is \(D_i\).
从山脚到山顶的小径被分为 \(N\) 个路段,每个路段有一个表示攀登难度的难度评级。第 \(i\) 个路段(\(1 \leq i \leq N\))的难度为 \(D_i\)

Takahashi starts the climb with stamina \(S\) and passes through all sections in order from the \(1\)-st to the \(N\)-th. Even if his stamina drops to \(0\) or below during the climb, he continues onward without stopping until the end.
高桥以体力值 \(S\) 开始攀登,并按顺序从第 \(1\) 个到第 \(N\) 个路段通过所有路段。即使在攀登过程中他的体力值降至 \(0\) 或以下,他也不会停止,直到攀登结束。

Takahashi can be in either an "exhausted state" or a "non-exhausted state." He starts the climb in a non-exhausted state. Once he becomes exhausted, he remains exhausted for the rest of the climb, regardless of how much stamina he recovers afterward.
高桥可能处于"疲劳状态"或"非疲劳状态"。他开始攀登时处于非疲劳状态。一旦他进入疲劳状态,无论此后恢复多少体力,他都会在剩余的攀登过程中保持疲劳状态。

When passing through each section \(i\) \((1 \leq i \leq N)\), the following steps are performed in this order:
当通过每个路段 \(i\)\(1 \leq i \leq N\))时,按以下顺序执行步骤:

  • Stamina consumption: If Takahashi is in a non-exhausted state, his stamina decreases by \(D_i\). If he is in an exhausted state, his stamina decreases by \(2 \times D_i\).
    体力消耗:如果高桥处于非疲劳状态,他的体力减少 \(D_i\)。如果他处于疲劳状态,他的体力减少 \(2 \times D_i\)
  • Exhaustion check: If his stamina after consumption is \(0\) or below and he is currently in a non-exhausted state, Takahashi becomes exhausted. (If he is already exhausted, nothing happens.)
    疲劳检查:如果消耗后的体力为 \(0\) 或以下,并且他当前处于非疲劳状态,则高桥进入疲劳状态。(如果他已处于疲劳状态,则不发生任何变化。)
  • Mountain hut recovery: If there is a mountain hut immediately after passing through section \(i\), his stamina increases by the recovery amount of that hut. If there is no hut, nothing happens. There is no upper limit on stamina, and it can exceed the initial stamina.
    山屋恢复:如果在通过路段 \(i\) 后立即有一个山屋,他的体力增加该山屋的恢复量。如果没有山屋,则不发生任何变化。体力没有上限,可以超过初始体力。

There are several mountain huts along the trail. There are \(M\) huts (possibly \(0\)), and the \(j\)-th hut \((1 \leq j \leq M)\) is located immediately after passing through section \(P_j\), providing a stamina recovery of \(R_j\). Mountain huts can only exist immediately after sections \(1\) through \(N-1\). There is no mountain hut immediately after section \(N\) (the last section).
沿小径有几个山屋。有 \(M\) 个山屋(可能为 \(0\)),第 \(j\) 个山屋(\(1 \leq j \leq M\))位于通过路段 \(P_j\) 后立即的位置,提供 \(R_j\) 的体力恢复。山屋只能位于通过路段 \(1\)\(N-1\) 后立即的位置。路段 \(N\)(最后一个路段)后没有山屋。

Determine Takahashi's remaining stamina when he arrives at the summit after passing through all \(N\) sections.
确定高桥在通过所有 \(N\) 个路段后到达山顶时的剩余体力。

【输入】

\(N\) \(M\) \(S\)
\(D_1\) \(D_2\) \(\ldots\) \(D_N\)
\(P_1\) \(R_1\)
\(P_2\) \(R_2\)
\(\vdots\)
\(P_M\) \(R_M\)

  • The first line contains the number of sections \(N\), the number of mountain huts \(M\), and the initial stamina \(S\), separated by spaces.
  • The second line contains the difficulties \(D_1, D_2, \ldots, D_N\) of each section, separated by spaces.
  • The following \(M\) lines contain information about the mountain huts. If \(M = 0\), this part does not exist.
  • The \((2 + j)\)-th line contains the section number \(P_j\) where the \(j\)-th mountain hut is located and the recovery amount \(R_j\), separated by spaces. The mountain hut information is not necessarily given in ascending order of \(P_j\).

【输出】

Output in a single line the remaining stamina of Takahashi after he has passed through all sections. The stamina may be a negative value.

【输入样例】

3 1 10
3 4 2
2 3

【输出样例】

4

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, m, s;  // n: 天数,m: 奖励次数,s: 初始体力值
int d[N];  // d[i]: 第i天消耗的体力
int b[N];  // b[i]: 第i天获得的奖励体力

signed main()
{
    cin >> n >> m >> s;  // 读入天数、奖励次数、初始体力值
    
    for (int i = 1; i <= n; i++)
    {
        cin >> d[i];  // 读入每天消耗的体力
    }
    
    for (int i = 1; i <= m; i++)
    {
        int p, r; 
        cin >> p >> r;  // 读入奖励的天数和体力值
        b[p] = r;  // 在第p天获得r点体力
    }
    
    bool flag = 0;  // 标记是否曾体力耗尽过(flag=0: 未耗尽,flag=1: 曾耗尽)
    
    for (int i = 1; i <= n; i++)  // 模拟每一天
    {
        if (flag == 0)  // 如果从未耗尽过体力
        {
            s -= d[i];  // 正常消耗体力
        }
        else  // 如果曾经耗尽过体力
        {
            s -= 2 * d[i];  // 双倍消耗体力
        }
        
        if (s <= 0)  // 如果体力耗尽
        {
            flag = 1;  // 标记为曾耗尽过
        }
        
        s += b[i];  // 获得当天奖励体力
        
        // 调试输出(被注释掉)
        // cout << "s " << s << endl;
    }
    
    cout << s << endl;  // 输出最终体力值
    return 0;
}

【运行结果】

3 1 10
3 4 2
2 3
4

C - Organizing the Bookshelf

【题目来源】

AtCoder:C - Organizing the Bookshelf

【题目描述】

Takahashi has decided to organize the bookshelf in his room. The bookshelf contains \(N\) books, and the thickness of the \(i\)-th book (\(1 \leq i \leq N\)) is \(V_i\). Two books with different indices may have the same thickness.
高桥决定整理他房间里的书架。书架上有 \(N\) 本书,第 \(i\) 本书(\(1 \leq i \leq N\))的厚度为 \(V_i\)。不同编号的两本书可能有相同的厚度。

Takahashi wants to rearrange all \(N\) books into a single row in any order, using each book exactly once. Since a large difference in thickness between adjacent books looks unappealing, he wants to rearrange the books so that the sum of absolute differences of thicknesses between adjacent books is minimized.
高桥想将所有 \(N\) 本书以任意顺序重新排列成一行,每本书恰好使用一次。由于相邻书籍之间厚度差异过大会显得不美观,他希望重新排列书籍,使得相邻书籍厚度差的绝对值之和最小。

Specifically, let \(A_k\) denote the thickness of the \(k\)-th book from the left after rearranging. Here, \((A_1, A_2, \ldots, A_N)\) is a permutation of \((V_1, V_2, \ldots, V_N)\). Find the minimum value of:
具体来说,设 \(A_k\) 表示重新排列后从左数第 \(k\) 本书的厚度。这里,\((A_1, A_2, \ldots, A_N)\)\((V_1, V_2, \ldots, V_N)\) 的一个排列。求以下式子的最小值:

\(\sum_{k=1}^{N-1} |A_k - A_{k+1}|\)

【输入】

\(N\)
\(V_1\) \(V_2\) \(\ldots\) \(V_N\)

  • The first line contains an integer \(N\), representing the number of books.
  • The second line contains \(N\) integers \(V_1, V_2, \ldots, V_N\) separated by spaces, representing the thickness of each book.

【输出】

Print the minimum value of the sum of absolute differences of thicknesses between adjacent books as an integer on a single line.

【输入样例】

4
3 1 4 2

【输出样例】

3

【解题思路】

image

【代码详解】

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

signed main()
{
    cin >> n;  // 读入数字个数
    
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i];  // 读入每个数字
    }
    
    sort(v + 1, v + n + 1);  // 对数字进行升序排序
    
    for (int i = 2; i <= n; i++)  // 计算相邻数字的差值的总和
    {
        ans += v[i] - v[i - 1];  // 累加相邻数字的差值
    }
    
    cout << ans << endl;  // 输出结果
    return 0;
}

【运行结果】

4
3 1 4 2
3

D - Wi-Fi Spot Connection

【题目来源】

AtCoder:D - Wi-Fi Spot Connection

【题目描述】

Takahashi is trying to walk along a long corridor.
高桥正试图沿着一条长廊行走。

This corridor is represented as the closed interval \([0, L]\) on a number line. Takahashi walks straight through the corridor from the start point at coordinate \(0\) to the goal point at coordinate \(L\).
这条长廊在数轴上表示为闭区间 \([0, L]\)。高桥从起点坐标 \(0\) 出发,沿着长廊直线行走至终点坐标 \(L\)

There are \(N\) Wi-Fi routers installed in the corridor. The \(i\)-th router \((1 \leq i \leq N)\) is installed at coordinate \(X_i\) and transmits a signal to all points within distance \(R_i\) from it (including points at exactly distance \(R_i\)). That is, the coverage area of the \(i\)-th router is the closed interval \([X_i - R_i, X_i + R_i]\). Note that multiple routers may be installed at the same coordinate.
走廊中安装了 \(N\) 个 Wi-Fi 路由器。第 \(i\) 个路由器(\(1 \leq i \leq N\))安装在坐标 \(X_i\) 处,并向距离其 \(R_i\) 以内的所有点(包括距离恰好为 \(R_i\) 的点)发送信号。也就是说,第 \(i\) 个路由器的覆盖范围是闭区间 \([X_i - R_i, X_i + R_i]\)。注意,多个路由器可能安装在同一坐标。

Since Takahashi is making an online call on his smartphone while moving, he needs to be connected to Wi-Fi at every point along the corridor.
由于高桥在移动过程中通过智能手机进行在线通话,他需要在长廊的每个点上都连接到 Wi-Fi。

Determine whether every coordinate in the closed interval \([0, L]\) is covered by at least one of the \(N\) routers. If a router's coverage area extends beyond the closed interval \([0, L]\), the portion outside the interval does not affect the determination. It is sufficient that the portion within the closed interval \([0, L]\) is properly covered.
判断闭区间 \([0, L]\) 中的每个坐标是否至少被 \(N\) 个路由器中的一个覆盖。如果某个路由器的覆盖范围超出了闭区间 \([0, L]\),超出区间的部分不影响判断。只要在闭区间 \([0, L]\) 内的部分被完全覆盖即可。

【输入】

\(N\) \(L\)
\(X_1\) \(R_1\)
\(X_2\) \(R_2\)
\(\vdots\)
\(X_N\) \(R_N\)

  • The first line contains an integer \(N\) representing the number of routers and an integer \(L\) representing the coordinate of the goal point, separated by a space.
  • From the 2nd line to the \((N + 1)\)-th line, the information of each router is given.
  • The \((1 + i)\)-th line contains an integer \(X_i\) representing the coordinate of the \(i\)-th router and an integer \(R_i\) representing the radius of its signal range, separated by a space.

【输出】

If every coordinate in the closed interval \([0, L]\) is covered by at least one router's coverage area, print Yes; otherwise, print No.

【输入样例】

3 10
2 3
5 2
8 3

【输出样例】

Yes

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, l;  // n: 路由器数量, l: 走廊长度
struct Node
{
    int l, r;  // 路由器覆盖区间的左边界和右边界
}a[N];

// 比较函数,用于排序
bool cmp(Node x, Node y)
{
    if (x.l != y.l)  // 首先按左边界从小到大排序
    {
        return x.l < y.l;
    }
    return x.r < y.r;  // 左边界相同时,按右边界从小到大排序
}

int main()
{
    // 读入路由器数量和走廊长度
    cin >> n >> l;
    
    // 读入每个路由器的位置和覆盖半径,计算覆盖区间
    for (int i = 1; i <= n; i++)
    {
        int x, r;  // x: 路由器位置, r: 覆盖半径
        cin >> x >> r;
        a[i].l = max(0, x - r);    // 左边界不能小于0
        a[i].r = min(l, x + r);    // 右边界不能大于l
    }
    
    // 将路由器按覆盖区间排序
    sort(a + 1, a + n + 1, cmp);
    
    int r = 0;  // 当前已覆盖到的最右位置,初始为0
    
    // 贪心算法:遍历所有路由器
    for (int i = 1; i <= n && r < l; i++)
    {
        // 检查是否有间隙:如果当前路由器左边界 > 已覆盖最右位置+1,说明有覆盖不到的区域
        if (a[i].l > r + 1)
        {
            cout << "No" << endl;
            return 0;
        }
        
        int maxr = 0, maxi = i;  // maxr: 能找到的最大右边界, maxi: 对应路由器的索引
        
        // 在左边界 <= 当前已覆盖位置的路由器中,找到右边界最大的
        for (int j = i; j <= n && a[j].l <= r; j++)
        {
            if (a[j].r > maxr)
            {
                maxr = a[j].r;  // 更新最大右边界
                maxi = j;       // 记录对应的路由器索引
            }
        }
        
        // 如果最大右边界 <= 当前已覆盖位置,说明无法继续扩展
        if (maxr <= r)
        {
            cout << "No" << endl;
            return 0;
        }
        
        r = maxr;    // 更新已覆盖的最右位置
        i = maxi;    // 跳转到具有最大右边界的路由器,继续处理
    }
    
    // 检查是否完全覆盖了走廊
    if (r >= l)
    {
        cout << "Yes" << endl;
    }
    else 
    {
        cout << "No" << endl;
    }
    
    return 0;
}

【运行结果】

3 10
2 3
5 2
8 3
Yes

E - Shelving Books on a Bookshelf

【题目来源】

AtCoder:E - Shelving Books on a Bookshelf

【题目描述】

Takahashi, working as a librarian, has been assigned the task of shelving \(N\) books onto a bookshelf.
高桥作为一名图书管理员,被分配了一项任务,要将 \(N\) 本书上架到一个书架上。

The bookshelf has \(M\) empty spaces arranged in a row, numbered from left to right as space \(1\), space \(2\), \(\ldots\), space \(M\). Each space \(j\) has an integer value \(C_j\) representing its "weight capacity," and each space can hold at most \(1\) book.
书架上有 \(M\) 个空位排成一行,从左到右编号为位置 \(1\), 位置 \(2\), \(\ldots\), 位置 \(M\)。每个位置 \(j\) 有一个整数值 \(C_j\) 表示其"承重能力",每个位置最多能放 \(1\) 本书。

The books are numbered from \(1\) to \(N\), and book \(i\) has an integer value \(W_i\) representing its "weight."
书籍编号从 \(1\)\(N\),书 \(i\) 有一个整数值 \(W_i\) 表示其"重量"。

Takahashi determines the placement for each book one at a time, in the order book \(1\), book \(2\), \(\ldots\), book \(N\), using the following procedure:
高桥按照书籍 \(1\), 书籍 \(2\), \(\ldots\), 书籍 \(N\) 的顺序,使用以下步骤逐一确定每本书的放置位置:

  • Among the spaces that do not yet have a book placed on them, consider as candidates those whose weight capacity is at least the weight of the book (i.e., \(C_j \geq W_i\)).
    在尚未放置书籍的位置中,考虑那些承重能力不低于书籍重量的位置(即 \(C_j \geq W_i\))作为候选位置。
  • If there is at least one candidate, place the book on the candidate space with the smallest number. The space where a book is placed becomes occupied and can no longer be selected for subsequent books.
    如果至少有一个候选位置,则将这本书放在编号最小的候选位置上。被放置书籍的位置变为已占用,不能再为后续书籍所选。
  • If there are no candidates, give up on shelving that book. A book that is given up on is not placed on the bookshelf and is never reconsidered.
    如果没有候选位置,则放弃上架这本书。被放弃的书籍不会被放置在书架上,且后续也不再被考虑。

After considering the placement for all books, determine the number of books that were successfully placed on the bookshelf.
在考虑了所有书籍的放置后,确定成功放置在书架上的书籍数量。

【输入】

\(N\) \(M\)
\(W_1\) \(W_2\) \(\ldots\) \(W_N\)
\(C_1\) \(C_2\) \(\ldots\) \(C_M\)

  • The first line contains \(N\), the number of books, and \(M\), the number of spaces on the bookshelf, separated by a space.
  • The second line contains the weights of each book \(W_1, W_2, \ldots, W_N\), separated by spaces.
  • The third line contains the weight capacities of each space \(C_1, C_2, \ldots, C_M\), separated by spaces.

【输出】

Print the number of books that were successfully placed on the bookshelf, on a single line.

【输入样例】

4 5
3 5 2 7
4 6 3 8 2

【输出样例】

4

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005, INF = 1e9;
int n, m, cnt;  // n: 任务数量,m: 机器数量,cnt: 可完成的任务数
int w[N], c[N];  // w[i]: 第i个任务所需容量,c[i]: 第i台机器的容量

struct Node
{
    int l, r;  // 区间左右端点
    int dt, mx;  // dt: 懒标记,mx: 区间最大值
}tr[N * 4];  // 线段树数组,开4倍空间

// 从子节点更新父节点的信息
void pushup(int u)
{
    tr[u].mx = max(tr[u << 1].mx, tr[u << 1 | 1].mx);  // 取左右子树的最大值
}

// 下传懒标记
void pushdown(int u)
{
    auto &root = tr[u], &l = tr[u << 1], &r = tr[u << 1 | 1];
    l.dt += root.dt, l.mx += root.dt;  // 更新左子树
    r.dt += root.dt, r.mx += root.dt;  // 更新右子树
    root.dt = 0;  // 清空当前节点的懒标记
}

// 构建线段树
void build(int u, int l, int r)
{
    if (l == r)  // 叶节点
    {
        tr[u] = {l, r, 0, c[l]};  // 初始懒标记为0,值为机器容量
    }
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);  // 递归构建左右子树
        pushup(u);  // 更新当前节点的值
    }
}

// 单点更新:将位置pos的值更新为d
void update(int u, int pos, int d)
{
    if (tr[u].l == tr[u].r)  // 找到叶节点
    {
        tr[u].mx = d;  // 更新值
        return;
    }
    else
    {
        pushdown(u);  // 下传懒标记
        int mid = tr[u].l + tr[u].r >> 1;
        if (pos <= mid)  // 在左子树
        {
            update(u << 1, pos, d);
        }
        if (pos > mid)  // 在右子树
        {
            update(u << 1 | 1, pos, d);
        }
        pushup(u);  // 更新当前节点的值
    }
}

// 区间查询:查询区间[l, r]的最大值
int query(int u, int l, int r)
{
    if (tr[u].l >= l && tr[u].r <= r)  // 当前节点完全包含在查询区间内
    {
        return tr[u].mx;
    }
    else
    {
        pushdown(u);  // 下传懒标记
        int mid = tr[u].l + tr[u].r >> 1;
        int res = -INF;  // 初始化为负无穷
        if (l <= mid)  // 与左子树有交集
        {
            res = query(u << 1, l, r);
        }
        if (r > mid)  // 与右子树有交集
        {
            res = max(res, query(u << 1 | 1, l, r));  // 取最大值
        }
        return res;
    }
}

// 在区间[l, r]中查找第一个大于等于val的位置,找不到返回-1
int find(int u, int l, int r, int val)
{
    if (tr[u].mx < val)  // 当前区间最大值小于val,不可能找到
    {
        return -1;
    }
    if (tr[u].l == tr[u].r)  // 叶节点
    {
        return tr[u].l;  // 返回位置
    }
    
    int mid = (tr[u].l + tr[u].r) >> 1;
    int res = -1;
    if (l <= mid)  // 先在左子树找
    {
        res = find(u << 1, l, r, val);
    }
    if (res == -1 && r > mid)  // 左子树没找到,在右子树找
    {
        res = find(u << 1 | 1, l, r, val);
    }
    return res;
}

int main()
{
    cin >> n >> m;  // 读入任务数量和机器数量
    
    for (int i = 1; i <= n; i++)
    {
        cin >> w[i];  // 读入每个任务所需容量
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> c[i];  // 读入每台机器的容量
    }
    
    build(1, 1, m);  // 构建线段树,管理机器容量
    
    for (int i = 1; i <= n; i++)  // 遍历每个任务
    {
        // 查找第一个容量大于等于w[i]的机器
        int pos = find(1, 1, m, w[i]);
        if (pos != -1)  // 找到了合适的机器
        {
            cnt++;  // 可完成的任务数加1
            update(1, pos, -INF);  // 将该机器的容量设为负无穷,表示已使用
        }
    }
    
    cout << cnt << endl;  // 输出可完成的任务数
    return 0;
}

【运行结果】

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