Cocoicobird
热爱永远可以成为你继续下去的理由

今日刷题:\(1071-1072\)

1071 NC53681 「土」巨石滚滚

题目描述

帕秋莉掌握了一种土属性魔法

她使用这种魔法建造了一个大型的土球,并让其一路向下去冲撞障碍

土球有一个稳定性 \(x\),如果 \(x < 0\),它会立刻散架

每冲撞一个障碍,土球会丧失 \(a_i\) 的稳定性,冲撞之后,又会从障碍身上回馈 \(b_i\) 的稳定性

帕秋莉想知道,如果合理的安排障碍的顺序,在保证土球不散架的情况下,是否可以将障碍全部撞毁呢?

输入描述

输入一个整数 \(T\),代表 \(T\) 组数据,每组数据中:
前一行两个整数 \(n , m\),表示障碍个数和土球的稳定性
接下来一行两个整数,分别表示障碍的 \(a_i\)\(b_i\)

输出描述

若可以,输出 Yes(不含引号),否则输出 No(不含引号)

示例

输入

1
5 50
49 49
52 0
5 10
26 24
70 70

输出

No
备注

\(Σn <= 500000, 1<=m<=100000,0<=a,b<=100000\)

解题思路

为了保证顺利通过所有障碍:首先优先通过可以增加稳定性的障碍,即 \(b_i-a_i>=0\) 的障碍,在这些障碍中,损失 \(a_i\) 小的优先(因为通过障碍需要先减少稳定性,后增加);其次,对于通过减少稳定性的障碍,则优先通过 \(b_i\) 更大的障碍。

C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
typedef pair<int, int> PII;

int T;
int n, m;
PII a[N];

bool cmp(PII a, PII b) {
    int ac = a.second - a.first, bc = b.second - b.first;
    if (ac * bc <= 0)
        return ac > bc;
    else if (ac >= 0 && bc >= 0)
        return a.first < b.first;
    else
        return a.second > b.second;
}
// 先减少后增加
int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++)
            scanf("%d%d", &a[i].first, &a[i].second);
        sort(a, a + n, cmp);
        long long cnt = m;
        for (int i = 0; i < n; i++) {
            cnt -= (long long) a[i].first;
            if (cnt < 0)
                break;
            cnt += (long long) a[i].second;
        }
        if (cnt < 0)
            puts("No");
        else
            puts("Yes");
    }
    return 0;
}

1072 NC25044 [USACO 2007 Jan S]Tallest Cow

题目描述

FJ's \(N\) (\(1 ≤ N ≤ 10,000\)) cows conveniently indexed \(1..N\) are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height \(H\) (\(1 ≤ H ≤ 1,000,000\)) of the tallest cow along with the index \(I\) of that cow.
FJ has made a list of \(R\) (\(0 ≤ R ≤ 10,000\)) lines of the form "cow 17 sees cow 34". This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17.
For each cow from \(1..N\), determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints.

输入描述

Line \(1\): Four space-separated integers: \(N, I, H\) and \(R\)
Lines \(2..R+1\): Two distinct space-separated integers \(A\) and \(B\) (\(1 ≤ A, B ≤ N\)), indicating that cow A can see cow B.

输出描述

Lines \(1..N\): Line i contains the maximum possible height of cow i.

示例

输入

9 3 5 5
1 3
5 3
4 3
3 7
9 8

输出

5
4
5
3
4
4
5
5
5
解题思路

对于 \(x\) 可以看到 \(y\)(假设 \(x\le y\)),则 \(h_x\le h_y\),且二者之间的牛 \(i\) 满足 \(h_i<h_x\),按照题意需要每个牛尽量高,则取 \(h_x=h_y\)\(h_i=h_x-1\)
那么是否有可能 \(h_x<h_y\)?假设存在,则说明 \(x\) 会更多的出现在其余组之间,导致其被多次减一,则有 \([a,b]\) 使得 \(h_a<h_x\le h_b<h_y\),而 与 \(h_b<h_x\) 矛盾,因此 \(h_x=h_y\)

C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 10010;

int n, I, H, m;
int h[N];
set<pair<int, int>> S;

int main() {
    scanf("%d%d%d%d", &n, &I, &H, &m);
    for (int i = 0; i < m; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        if (l > r)
            swap(l, r);
        if (S.find({l , r}) == S.end()) {
            h[l + 1]--;
            h[r]++;
            S.insert({l, r});
        }
    }
    for (int i = 1; i <= n; i++) {
        h[i] += h[i - 1];
        printf("%d\n", h[i] + H);
    }
    return 0;
}
posted on 2026-03-04 11:06  Cocoicobird  阅读(1)  评论(0)    收藏  举报