CodeForces - 1469C - Building a Fence (思维)

简介: 笔记

Building a Fence


题意

用 n个宽度为1高度为k 的木板构建一段栅栏 第i个木板下面的地面高度等于 h i第一个和最后一个木板必须在地面上 其他的木板 底端 可能位于地面或者不高于地面k−1的高度上 相邻的两个木板必须有公共边 也即有重合的部分 问有没有可能建造一个符合所有规则的围栏


思路

设 l ll r rr 分别为当前栅栏下端的最小高度和最大高度 因为每段栅栏高度都为 k kk 可知 下一段栅栏底边高度的范围为[l−k+1,r+k−1] 又因为 栅栏底边最低要在地上即a[i] 最高只能达到 $a[i] + k - 1 $ 所以更新后的 lr为:

l = max(l - k + 1, a[i]);
r = min(r + k - 1, a[i] + k - 1);

如果l<=r 说明可行

否则不可行

最后特判一下最后一块栅栏(只能建造在地上) 即判断一下 a[n] 是否在[l,r] 的范围内


代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
inline LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; }
const int N = 200010;
int n, k;
int a[N];
void solve() {
  cin >> n >> k;
  for (int i = 1; i <= n; ++i)scanf("%d", &a[i]);
  bool flag = true;
  int l = a[1], r = a[1]; //栅栏修建的范围 即栅栏底边高度的范围
  for (int i = 2; i <= n; ++i) {
    l = max(l - k + 1, a[i]);
    r = min(r + k - 1, a[i] + k - 1);
    if (l > r) {
      flag = false;
      break;
      //cout << "i  " << i << endl;
    }
  }
  if (a[n] < l || a[n] > r)flag = false;
  if (flag)puts("YES");
  else puts("NO");
}
int main() {
  int t; cin >> t;
  while (t--)
    solve();
  return 0;
}


目录
相关文章
codeforces 285C - Building Permutation
题目大意是有一个含n个数的数组,你可以通过+1或者-1的操作使得其中的数是1--n中的数,且没有重复的数。 既然是这样的题意,那么我就应该把原数组中的数尽量往他最接近1--n中的位置放,然后求差绝对值之和,但有多个数,怎么使他们和最小,这样就要对其进行排序了,直接按大小给它们安排好位置,然后计算。
38 0
|
缓存 搜索推荐 NoSQL
每日一博 - Stack OveFlow Arch In Reality
每日一博 - Stack OveFlow Arch In Reality
51 0
practice2-基础算法2
快速学习practice2-基础算法2
practice2-基础算法2
|
人工智能
Codeforces-Adding Powers(进制问题+思维)
Codeforces-Adding Powers(进制问题+思维)
135 0
UCF 2021 Practice F.Balanced Strings (思维 组合数学)
UCF 2021 Practice F.Balanced Strings (思维 组合数学)
109 0
|
机器学习/深度学习
AtCoder Beginner Contest 218 F - Blocked Roads (最短路径还原 思维)
AtCoder Beginner Contest 218 F - Blocked Roads (最短路径还原 思维)
102 0
practice3-基础算法3
快速学习practice3-基础算法3
|
算法 Java C语言
practice1-基础算法
快速学习practice1-基础算法

热门文章

最新文章