2021牛客寒假演算法基礎集訓營5 D 石子遊戲

2021-10-19 21:13:03 字數 1594 閱讀 2351

題目鏈結

葉妹妹很喜歡玩石頭,於是這天澤鴿鴿給她出了一道石子遊戲,規則是這樣的:有 n

nn 堆石子排成一行,其中第 i

ii 堆石子有 a

ia_i

ai​ 個,葉妹妹可以選擇做無數次這種操作:每次操作把連續相鄰的 k

kk 個石子堆中的每堆石子數目加一,請問葉妹妹能否讓每堆石子的數目都相同呢?葉妹妹覺得這題太簡單了,於是丟給了聰明的你,快來解決這個問題吧!

第一行輸入樣例組數 ttt

對於每組樣例來說,第一行輸入兩個數 n

nn 和 kkk

第二行輸入 n

nn 個數,其中第 i

ii 個數為 a

ia_i

ai​輸出總共 t

tt 行,對於每組樣例來說,如果能使每堆石子的數目都相同則輸出乙個整數 x

xx,x

xx 表示達到相同時的最少的運算元;否則輸出 −1-1

−1

1

4 31 1 1 2

1
思維+差分~

這題我一開始想的是模擬,後來發現複雜度上天,忽然發現,可以用兩遍差分來判斷,我們先從左往右差分,在遍歷的過程中記錄最大值,並不斷將小於最大值的數修正,不難發現,一遍差分之後該數列下標 [1,

n−k+

1]

[1,n-k+1]

[1,n−k

+1] 的部分(因為限定連續 k

kk 個數,所以右端點只能到 n−k

+1

n-k+1

n−k+

1)會變成非嚴格上公升子串行,此時只需要再從右往左再進行一遍差分,判斷陣列是否修正成一樣的數即可~

想法很簡單,但是一邊差分一邊修正這個過**的很難寫,一不小心就掛了,我具體講一下用到的兩個變數:

這些變數的位置尤為重要,首先我們要先更新 sum,其次更新 a[i],最後再更新 diff 陣列,詳見**:

#include

using

namespace std;

typedef

long

long ll;

const

int n =

1e5+5;

int t, n, k;

ll a[n]

, diff[n]

, mx, sum, ans;

void

init()

intmain()

mx =

max(mx, a[i]);

}init()

;for

(ll i = n; i >=

1; i--

) mx =

max(mx, a[i]);

}int flag =0;

for(ll i =

1; i <= n -

1; i++)}

if(flag)

printf

("-1\n");

else

printf

("%lld\n"

, ans);}

return0;

}

2021牛客寒假演算法基礎集訓營3

三場牛客下來覺得自己越來越不在狀態,思路不清晰,一下手就是bug,每調完一題刷下榜都被甩開十里地,罰時慘不忍睹 傳送門 簽到 include using namespace std typedef long long ll const ll inf 0x3f3f3f3f const ll mod 1...

2021牛客寒假演算法基礎集訓營1

題目描述 請你構造乙個非空的括號字串,包含正好 k 個不同合法括號對。所謂括號字串,是指由 和 這兩種字元構成的字串。要求構造的字串長度不超過100000。輸入描述 乙個整數 k。乙個整數 kk。0 k 1e9 輸出描述 乙個僅包含左右括號字串,其中有 kk 個合法的括號對。如果有多種構造方法,輸出...

2021牛客寒假演算法基礎集訓營6

思路 k1排k2前面滿足 k1.a k2.ax k2.b k1.b k1.ax k1.b k2.b k2.ak1.b k2.b k1.a k2.a k1.b include define ull unsigned long long define ll long long const int inf...