101-最高的牛

题目描述

关系

4007-非零段划分
2014-岛

内容

N 头牛站成一行,被编队为 123N,每头牛的身高都为整数。

当且仅当两头牛中间的牛身高都比它们矮时,两头牛方可看到对方。

现在,我们只知道其中最高的牛是第 P 头,它的身高是 H ,剩余牛的身高未知。

但是,我们还知道这群牛之中存在着 M 对关系,每对关系都指明了某两头牛 AB 可以相互看见。

求每头牛的身高的最大可能值是多少。

输入格式

第一行输入整数 N,P,H,M,数据用空格隔开。

接下来 M 行,每行输出两个整数 AB ,代表牛 A 和牛 B 可以相互看见,数据用空格隔开。

输出格式

一共输出 N 行数据,每行输出一个整数。

i 行输出的整数代表第 i 头牛可能的最大身高。

数据范围

1N5000,
1H1000000,
1A,B10000,
AB,
0M10000

输入样例:

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

输出样例:

5
4
5
3
4
4
5
5
5
注意:

问题分析

最初思路

可以发现假如我们有关系 M,表明 [l1,r+1] 之间的最大高度就为 min(a[l],a[r])1。只要区间的两端确定了,那么其区间内所有的高度都会被限制。

我们更加倾向于从最高的牛开始考虑。先找到距离 P 最远的关系 R,假设 P 为 3,R 为 1,Hp 为 5,那么 HR=5,区间 [2,2] 的最大高度就为 3-1=2 了。

同样,若 R 为 7,且那么 H7=5,区间 [4,6] 的最大高度就为 4。

特别的,如果关系是相邻的,那么就为最大高度 5.

对于每一个位置 x 的最大高度就是区间 [x,x] 的最大高度。当然,P 位置的高度是不变的。所以需要特别注意。

故而,所以跨越 P 位置的关系都是不可能存在的。我们应该对所有跨越 P 的关系不处理。


最开始,所有位置的最大高度为 5。

思路分析

执行流程设计

  1. 初始化差分数组 b 为 5.
  2. 遍历所有的关系,假设关系为 [l,r]
    1. 如果 lPR,那么就不处理;
    2. 如果不是上述情况,就对区间 [l1,r1] 执行区间减 1 操作;
  3. 生成最后操作的数组,就是最后的答案;

总结

代码实现

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

#define x first
#define y second

typedef pair<int, int> pii;
typedef long long ll;

const int N = 5010, H = 1000010, M = 10010;
int n, p, h, m;
int b[M];
set<pii> re;

int main()
{
    cin >> n >> p >> h >> m;
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        if (a > b) swap(a, b);
        re.insert({a, b});
    }
    
    b[1] = h;
    for (auto v: re) {
        int d = v.y - v.x - 1;
        if (d > 0 && (v.y <= p || v.x >= p)) {
            b[v.x + 1] += -1;
            b[v.y] -= -1;
        }
    }
    
    ll s = 0;
    for (int i = 1; i <= n; i++) {
        s += b[i];
        cout << s << endl;
    }
    
    return 0;
}