Tallest Cow

题目链接
不想跳转链接的也可以直接滑到页面最底下

算法:差分

分析:

对原问题进行抽象, 可以简单的描述为一组序列在r个约束条件下能够每个元素能达到的最大值, 限制条件具体概述为开区间(a, b)中的每一个数<min(a, b)。

不同的约束关系之间有两种关系, 嵌套和交叉
交叉:有a<b<c<d, 其中(a, c)是一组约束条件, (b, d)是另一组约束条件。
分析可知开区间(a, c)中的所有元素<min(a, c), 开区间(b, d)中的所有元素<min(b, d), 其中推断有b<min(a, c), 与(b, d)中的所有元素<min(b ,d)矛盾, 由此可以知道, 约束条件不存在交叉关系
嵌套:有a<b<c<d, 其中(a, d)为一组, (b, c)为一组, 很容易知道, 可以轻易满足开区间(a, d)中的所有元素<min(a, d), 开区间(b, c)中的所有元素<min(b, c)
其实还有一种”相接“的关系, 即a<b<c, (a, b)和(b, c), 由最终通过了测试可知道, 不影响作答

考虑到维护的是数组区间, 且更大范围的约束条件包裹小范围的约束条件时, 需要保证约束条件间相对高度不变, 所以这里维护差分数组是很好的选择。笔者当时写这题更多想的是维护区间所以用的差分数组

为了使序列尽可能的大, 又不让它超过最高h, 选择让序列初始值为h

小细节:题目提到了约束条件可能会重复,重复对同一个约束条件约束区间, 会使序列过小, 所以我们还需要去重

下面给出代码

#include <iostream>
#include <vector>
#include <algorithm>

const int maxn = 1e4 + 10;
int n, i, h, r, a[maxn];

int main()
{
	//平平无奇的读入数据
	std::cin >> n >> i >> h >> r;
	std::vector<std::pair<int, int>>vec(r + 10, { 0, 0 });
	for (int i = 1; i <= r; ++i)
	{
		std::cin >> vec[i].first >> vec[i].second;
		//因为要对数据去重, 所以约束条件(a, b)最好是a<b
		//这里对数据作一下预处理
		if (vec[i].first > vec[i].second)
			std::swap(vec[i].first, vec[i].second);
	}
	
	//下面是普通的排序+去重
	std::sort(vec.begin() + 1, vec.begin() + r + 1, [](
		std::pair<int, int>a, std::pair<int, int>b)->bool
		{
			if (a.first != b.first) a.first < b.first;
			return a.second < b.second;
		});

	r = std::unique(vec.begin() + 1, vec.begin() + 1 + r, [](
		std::pair<int, int>a, std::pair<int, int>b)->bool
		{
			return (a.first == b.first && a.second == b.second);
		}) - (vec.begin() + 1);

	a[1] += h;//另差分数组a[1]=h, 这样序列初值就为h了
	for (int i = 1; i <= r; ++i)
	{
		//有约束条件(a, b), 那么需要对区间开区间(a, b)所有值减去1
		//以满足约束条件的最低要求
		int l = vec[i].first + 1, r = vec[i].second;
		--a[l], ++a[r];
	}
	
	//朴实无华的输出
	int num = 0;
	for (int i = 1; i <= n; ++i)
	{
		num += a[i];
		std::cout << num << '\n';
	}

	return 0;
}

----------------------------------------------------------------------------------

【题目描述】

FarmerJohn 有n头牛,它们按顺序排成一列。FarmerJohn 只知道其中最高的奶牛的序号及它的高度,其他奶牛的高度都是未知的。现在 FarmerJohn 手上有 R R R 条信息,每条信息上有两头奶牛的序号( a a a b b b),其中 b b b 奶牛的高度一定大于等于 a a a 奶牛的高度,且 a , b a, b a,b之间的所有奶牛的高度都比 a a a 小。现在 FarmerJohn 想让你根据这些信息求出每一头奶牛的可能的最大的高度。(数据保证有解)

【输入格式】

第一行:四个以空格分隔的整数: n , i , h , R n, i, h, R n,i,h,R n n n R R R 意义见题面; i i i h h h 表示第 i i i 头牛的高度为 h h h,他是最高的奶牛)

接下来 R R R 行:两个不同的整数 a a a b b b 1 ≤ a , b ≤ n 1 \le a, b \le n 1a,bn

【输出格式】

一共 n n n 行,表示每头奶牛的最大可能高度.

【数据范围】

1 ≤ n ≤ 10000 1 \le n \le 10000 1n10000 1 ≤ h ≤ 1000000 1 \le h \le 1000000 1h1000000 0 ≤ R ≤ 10000 0 \le R \le 10000 0R10000

样例 #1

样例输入 #1

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

样例输出 #1

5
4
5
3
4
4
5
5
5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值