题解:CF1291B Array Sharpening

liuli688

2023-12-03 20:59:37

题解

思路:

若数组的前 kf 项能够 sharpened 且数组的后 kb 项能够 sharpened,在 kf \ge kb 时可以将整个数组变 sharpened。

判定数组能被 sharpened 的方法:考虑使用贪心,将第 a_i 项减到最小,使数组严格单调递增或严格单调递减。

手玩样例:

#1:

[1001115978] 为例。

从前往后搜索:

100 \gets 0 11 \gets 1 15 \gets 2 9 \gets 3 7 \gets 4 8 \gets 5

始终没有出现不能将第 a_i 项减到最小的值,故有解。

#2:

[415411] 为例。

从前往后搜索:

4 \gets 0 1 \gets 1 5 \gets 2 4 \gets 3

此时,1 无法变成 4,则 kf \gets 3(我是按下标为 0 算的)。

从后往前搜索:

1 \gets 0 1 \gets 1 4 \gets 2 5 \gets 3

此时,1 无法变成 4,则 kb \gets 2

考虑扫描两次数组,第一次从前往后搜索,记录 $kf$,第二次从后往前搜索,记录 $kb$。然后判断是否 $kf \ge kb$ 便可得出结论。 ## 代码: ```cpp #include <bits/stdc++.h> using namespace std; int a[300005],n,t,kf,kb,i; int main() { ios::sync_with_stdio(0);//<iostream>加速 cin >> t; while(t--) { cin >> n; kf = -1;//记录特判 kb = -1; for(i = 0;i < n;i++) cin >> a[i]; for(i = 0;i < n;i++)//从前往后搜索 if(a[i] < i) { kf = i - 1; break; } for(i = n - 1;i >= 0;i--)//从后往前搜索 if(a[i] < n - i - 1) { kb = i + 1; break; } if(!(kf + 1) || !(kb + 1))//特判 { cout << "Yes\n"; continue; } if(kb <= kf)//正常判断 { cout << "Yes\n"; continue; } cout << "No\n"; } return 0; } ```