「上帝一声不响,一切皆由我定」|

BadBadBad__AK

园龄:1年6个月粉丝:13关注:6

P11596 [NOISG2018 Finals] Lightning Rod 题解

思路

我们使用 单调栈 来维护避雷针的分布。

1. 避雷针的保护范围

安装在建筑物 i 上的避雷针保护范围为:[xiyi,xi+yi]

2. 栈的维护逻辑

  • 栈中的元素记录建筑物编号,表示这些建筑物上安装了避雷针。
  • 弹出栈顶的条件:当当前建筑物的避雷针能够完全覆盖栈顶建筑物时,弹出栈顶。
  • 每次安装新避雷针后,将当前建筑物编号压入栈中。

3. 遍历规则

  • 动态调整每栋建筑物的避雷针保护范围,确保覆盖所有建筑物。
  • 遍历结束时,输出栈的大小。

代码实现

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

int x[10000005], y[10000005];
stack<int> st;

// 快速读入函数
inline int readInt() {
	int x = 0;
	char ch = getchar_unlocked();
	while (ch < '0' || ch > '9') ch = getchar_unlocked();
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar_unlocked();
	}
	return x;
}

int main() {
	int n;
	n = readInt();	// 读取建筑物数量
	for (int i = 1; i <= n; i++) {
		x[i] = readInt();
		y[i] = readInt();
	}

	int ty = x[1] - 1;	// 初始化保护范围
	for (int i = 1; i <= n; i++) {
		// 动态调整当前保护范围
		ty = max(ty - (x[i] - x[i - 1]), -1);
		if (ty >= y[i]) {
			continue;  // 当前建筑物已被保护
		}

		// 检查并更新栈
		while (!st.empty()) {
			if (y[st.top()] <= y[i] - (x[i] - x[st.top()])) {
				st.pop();  // 栈顶建筑物被替代
			} else {
				break;
			}
		}

		// 更新当前保护范围并压入栈
		ty = y[i];
		st.push(i);
	}

	// 输出最少避雷针数量
	cout << st.size();
	return 0;
}

本文作者:BadBadBad__AK

本文链接:https://www.cnblogs.com/BadBadBad/p/18691703/P11596

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   BadBadBad__AK  阅读(5)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起