题目:
3729. 改变数组元素
输入样例:
3
6
0 3 0 0 1 3
10
0 0 0 1 0 5 0 0 0 2
3
0 0 0
输出样例:
1 1 0 1 1 1
0 1 1 1 1 1 0 0 1 1
0 0 0
思路:
/*
题目要求对将该数组后一段都变成1,想到差分的操作
如果是我对这题用差分的话我可能会每次加1,然后特判如果已经是1的话则不需要加1
这样很傻也没必要
差分是将数组某一段加上一个数,而这道题是将数组某一段变成某个数,所以我们可以照样使用差分,但我们再去维护的时候是维护操作的次数,即不是0就变成1。
*/
代码:
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int T;
int n;
int V[N];
int b[N]; //设一个差分数组
void add(int l,int r,int x)
{
b[l]+=x;
b[r+1]-=x;
}
int main()
{
cin>>T;
while(T--)
{
memset(b,0,N*sizeof(int)); //每一次要将数组清空
cin>>n;
for(int i=1;i<=n;i++) //所以很多时候可以不用开一个数组来存,而是使用一次直接丢掉。为什么?
{
int t;
cin>>t;
if(t>i) t=i; //因为t可能比现有的0多,则可能发生数组越界,现有0的数量取决于n
add(i-t+1,i,t); //这里加t也可以,加1也可以,反正我们最后维护的是该位置上的数是否为0,只有0和非0两类
}
for(int i=1;i<=n;i++)
V[i]=V[i-1]+b[i]; //将差分数组前缀和
for(int i=1;i<=n;i++) //维护
if(V[i]!=0)
V[i]=1;
for(int i=1;i<=n;i++)
cout<<V[i]<<" ";
cout<<endl;
}
return 0;
}
结尾附上我刚开始写的2b暴力,真的很呆,只 过了8/10数据
#include <bits/stdc++.h>
using namespace std;
/*
暴力,能过通过了 8/10个数据
*/
const int N=200005;
int T,n;
int a[N];
int cnt=0; //表示V中现在有几个0
int main()
{
cin>>T;
while(T--)
{
int V[N]={0};
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
if(a[i]>=i)
for(int j=1;j<=i;j++)
V[j]=1;
else
while(a[i]--)
{
V[i-a[i]]=1;
}
}
for(int i=1;i<=n;i++) cout<<V[i]<<" ";
cout<<endl;
}
return 0;
}