2021 Niu Guest Winter Holiday Algorithm Basic Training Camp 5 D. Pebble Game (Differential)

D. Pebble game

Title link: https://ac.nowcoder.com/acm/contest/9985/D

Title description:

Sister Ye likes playing with stones, so Tian Ze Ge Ge played a stone game for her. The rules are as follows: There are n piles of stones in a row, and there are ai in the i-th pile of stones. Sister Ye can choose to do it countless times. This kind of operation: Each operation adds one to the number of each pile of stones in consecutive k piles of stones. Can sister Ye make the number of each pile of stones the same? Sister Ye thinks this question is too simple, so she threw it to the smart you, come and solve this problem!

Enter a description:

Enter the number of sample groups T in the first line

For each set of examples, enter two numbers n and k in the first line

The second input line number n, where ai is the i-th [agreed with the data size]

1≤T≤10,1≤n≤10^5 ,1≤k≤n,0≤ai≤10^9

Output description:

Output a total of T rows. For each group of examples, if the number of stones in each pile can be made the same, then output an integer x, where x represents the minimum number of operands when the same is reached; otherwise, output -1

Example 1:

Input
1
4 3
1 1 1 2
Output
1

Problem-solving ideas:

The difference
is operated from back to front. If any x>0 is found, it becomes 0 with x operations. For this question, given a suffix +1, (the n+1-kth position +1) will be affected, (that is, n+1%k congruential positions), so the negative numbers of these positions need to be set to 0.

code show as below:

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
int main(){
    
    
	int T;
	scanf("%d",&T);
	while(T--){
    
    
		int n,k,a[100010]={
    
    0};
		scanf("%d%d",&n,&k);
		for(int i=1;i<=n;i++){
    
    
			scanf("%d",&a[i]);
		}
		for(int i=n;i>=1;i--){
    
    
			a[i]-=a[i-1];  //求差分数组
		}
		ll ans=0;
		for(int i=n;i>=2;i--)
			if(i>k&&a[i]>0) 
				ans+=a[i],a[i-k]+=a[i],a[i]=0;
		int t=1;
		for(int i=2;i<=n;i++){
    
    
			if(a[i]<0&&(i%k==(n+1)%k))
				ans-=(n+1-i)/k*(ll)a[i],a[i]=0;  //特判
			t&=!a[i];
		}
		if(!t) ans=-1;
		printf("%lld\n",ans);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45894701/article/details/113952158