【Educational Codeforces Round 101 (Rated for Div. 2) C】Building a Fence

题目链接

链接

翻译

让你放长度为 \(k\) 的长条,相邻两列必须有一个公共位置,路不是平的,长条必须放在某个高度之上。

且最高不能高过路高上面 \(k-1\)

规定第一列和最后一列只能老老实实放在路面上。

问你能否符合上述要求放好所有的长条。

题解

每一列处理出来一个可能的长条占据的区域 \(Occpied\) 的上下界,然后以此来决定下一列可以放长条的上下界。

根据这个上下界,和第 \(i\) 列本来就有的,能放的区域 \(h_i+1,h_i+k\) 的限制,这两个区间取交集即可,如果为空则 \(NO\)

每一列都不为空,则 \(YES\)

边界特殊处理一下就好。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
 
const int N = 2e5;
 
int T, n, k;
LL h[N + 10];
 
int main() {
	#ifdef LOCAL_DEFINE
		freopen("in.txt", "r", stdin);
	#endif // LOCAL_DEFINE
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> T;
	
	while (T--) {
		cin >> n >> k;
		for (int i = 1; i <= n; i++) {
			cin >> h[i];
		}
		bool finalOK = true;
		LL minOccupied = h[1] + 1, maxOccupied = h[1] + k;
		for (int i = 2; i <= n; i++) {
			LL ithColumnCanPosMin, ithColumnCanPosMax;
			ithColumnCanPosMin = minOccupied - k + 1, ithColumnCanPosMax = maxOccupied;
			ithColumnCanPosMin = max(1LL, ithColumnCanPosMin);
			LL ithColumnToPosMin = h[i] + 1, ithColumnToPosMax = h[i] + k;
			if (i == n) {
				ithColumnToPosMax = h[i] + 1;
			}
			if (ithColumnCanPosMax < ithColumnToPosMin || ithColumnToPosMax < ithColumnCanPosMin) {
				finalOK = false;
			}
			ithColumnCanPosMin = max(ithColumnCanPosMin, ithColumnToPosMin);
			ithColumnCanPosMax = min(ithColumnCanPosMax, ithColumnToPosMax);
			minOccupied = ithColumnCanPosMin;
			maxOccupied = ithColumnCanPosMax + k - 1;
		}
		if (finalOK) {
			cout << "YES" << endl;
		}
		else {
			cout << "NO" << endl;
		}
	}
	return 0;
}
posted @ 2021-03-05 14:09  AWCXV  阅读(49)  评论(0编辑  收藏  举报