NC218534 石子游戏(思维)
这种以k为长度的,就想一个窗口一样,很多题都是按modk相等为一组判断的
这题也不例外,我们发现,将数组差分之后,相当于2-n都要是0,第一位是啥无所谓
那么从2开始枚举,因为第一位比较特殊,是啥无所谓,他们是0,如果当前小于0,那么我们在这把他补成0(这是唯一变成0的方法),因此i+k的位置就要对应减去。
做完上面一步后,如果和1是同一组的,那么如果他大于0,还可以通过1的差分使他变为0,这也是他唯一变成0的方法。但是因为只能长度为k所以1+2k的位置就需要多一次从1 - 1+k -1+2k
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const int N=1e5+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; ll b[N],a[N]; int main(){ ios::sync_with_stdio(false); int i; int t; cin>>t; while(t--){ int n,k; cin>>n>>k; for(i=1;i<=n;i++){ cin>>a[i]; b[i]=a[i]-a[i-1]; } ll res=0; int flag=0; for(i=2;i<=n;i++){ if(i+k<=n+1&&b[i]<0){ res+=(-b[i]); b[i+k]+=b[i]; b[i]=0; } } for(i=2;i<=n;i++){ if(b[i]>0){ if((i-1)%k==0){ res+=((i-1)/k*b[i]); } else{ flag=1; break; } } if(b[i]<0){ flag=1; break; } } if(flag){ cout<<-1<<endl; } else{ cout<<res<<endl; } } return 0; }
没有人不辛苦,只有人不喊疼