题目
有 N 头牛站成一行,被编队为 1、2、3…N,每头牛的身高都为整数。
当且仅当两头牛中间的牛身高都比它们矮时,两头牛方可看到对方。
现在,我们只知道其中最高的牛是第 P 头,它的身高是 H ,剩余牛的身高未知。
但是,我们还知道这群牛之中存在着 M 对关系,每对关系都指明了某两头牛 A 和 B 可以相互看见。
求每头牛的身高的最大可能值是多少。
输入格式
第一行输入整数 N,P,H,M,数据用空格隔开。
接下来 M 行,每行输出两个整数A 和 B ,代表牛 A 和牛 B 可以相互看见,数据用空格隔开。
输出格式
一共输出 N 行数据,每行输出一个整数。
第 i 行输出的整数代表第 i 头牛可能的最大身高。
数据范围
1≤N≤5000,
1≤H≤1000000,
1≤A,B≤10000,
0≤M≤10000
输入样例:
9 3 5 5
1 3
5 3
4 3
3 7
9 8
输出样例:
5
4
5
3
4
4
5
5
5
注意:
此题中给出的关系对可能存在重复
思路简介 (差分)
初看题目并没有想到差分,但看了一下算法标签是差分,就开始想用差分写了
先来讨论一下各组数据 a, b 的情况
1.假设 a1 = 1 b1 = 5 (值是下表,并不是高度)
只需要让 a1~b1内的牛 比 a1,b1 低 1 即可 (因为高度为整数,最小的差为一)
2.假设 a1 = 3 b1 = 6 , a2 = 4, b2 = 7 (值是下表,并不是高度)
因为 a1 可以看见 b1 故在a1 ~ b1中 a2 比 b1 低
因为 a2 可以看见 b2 故在a2 ~ b2中 b1 比 a2 低 假设矛盾
故数据每两头牛之间不可能存在交叉 即上方的情况
只有可能重合或部分重合
3.假设 a1 = 3 b1 = 7 , a2 = 4, b2 = 6 (值是下表,并不是高度)
只需要让a2,b2的高度比a1, b1 低 1 ,a2~b2内的高度比a2, b2 低 1 即可 (因为高度为整数,最小的差为一)
以此类推
当数据完全重合时不进行操作(判断是否重复各位大佬们各显神通就行,本蒟蒻刚学c++,不会map,set等等)
当数据不是完全重合时:
只需要利用差分的思想来对 ai ~ bi 内的值减一,通过求前缀和 并再加上最高的牛的高度就是每头牛最高的高度啦
代码如下:
#include <iostream>
using namespace std;
const int N = 5010;
bool judge[10001][10001]; // 用个二维数组记录是否重复(因为刚学c++,还不会用set,呜呜呜~)
int cattal[N]; // 差分数组
int main()
{
int n, p, h, m;
cin >> n >> p >> h >> m;
while (m--)
{
int a, b;
cin >> a >> b;
if (a > b) swap(a, b); // 题目中的 a, b大小没确定,记得交换一下
if (!judge[a][b]) // 如果没出现过
{
judge[a][b] = true;
cattal[a+1]--, cattal[b]++; // 差分模板, 记得是让 a后面 b前面的-1,不包括本身
}
}
for (int i = 1; i <= n; i++)
{
cattal[i] += cattal[i-1]; // 求差分的前缀和 再加上 和 h 就是身高啦
cout << cattal[i] + h << endl;
}
return 0;
}