分析
切入点,显然是样例,怎么都是01呢
思考一种构造方案:只需要把a[1]改成1,然后a[2]=后面元素个数。所以答案最多为2。
下面思考0和1的情况:
总结:需要看好求出答案需要记录几个量,适当开数组(从最容易想的nxt开始),然后利用递推关系一个一个求出来,后面就是无脑判断了。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=300010;
int t,n,a[maxn];
int nxt[maxn],num[maxn],mx[maxn],f[maxn];
/*下一个,跳几步,[i,n]num最大值,[i,n]改一个位置最大段数*/
int main()
{
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=2;i<=n;i++)
{
nxt[i]=i+a[i]+1;
}
num[n+1]=mx[n+1]=0;
for(int i=n;i>1;i--)
{
if(nxt[i]>n+1) num[i]=-1;
else if(num[nxt[i]]<0) num[i]=num[nxt[i]]-1;//不能跳完,-k步
else num[i]=num[nxt[i]]+1;
if(i==n) mx[i]=num[i];
else mx[i]=max(num[i],mx[i+1]);
if(nxt[i]<=n) f[i]=max(mx[i+1]+1,f[nxt[i]]+1);
else f[i]=max(0,mx[i+1])+1;
}
for(int i=1;i<=n-1;i++)
{
if(a[i]==num[i+1]) cout<<0<<' ';
else if(num[i+1]>0) cout<<1<<' ';
else if(f[i+1]>=a[i]) cout<<1<<' ';
else cout<<2<<' ';
}
cout<<endl;
// memset(nxt,0,sizeof(nxt));
// memset(num,0,sizeof(num));//不能加,会超时!!
// memset(mx,0,sizeof(mx));
// memset(f,0,sizeof(f));
}
return 0;
}