思路:
若数组的前 kf 项能够 sharpened 且数组的后 kb 项能够 sharpened,在 kf \ge kb 时可以将整个数组变 sharpened。
判定数组能被 sharpened 的方法:考虑使用贪心,将第 a_i 项减到最小,使数组严格单调递增或严格单调递减。
手玩样例:
#1:
以 [100,11,15,9,7,8] 为例。
从前往后搜索:
100 \gets 0
11 \gets 1
15 \gets 2
9 \gets 3
7 \gets 4
8 \gets 5
始终没有出现不能将第 a_i 项减到最小的值,故有解。
#2:
以 [4,1,5,4,1,1] 为例。
从前往后搜索:
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;
}
```