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

2021-10-19 19:29:39 字數 1671 閱讀 2341

前言:哎,這場打的就很nanshou,開局a出倆題,剩下的數學題興趣就直接無了,結果倆小時直接結束戰鬥。

結束之後看了一下題解,感覺d題講的有點麻煩,這邊講一下一種更低效率不過更加直觀的做法。如果有看不懂題解的朋友可以嘗試一下我的理解。

沒看過題目的可以去牛客先看一下。我這裡自己出一組資料。

15 2

3 3 2 0 2

這裡介紹乙個演算法,差分演算法,至於為什麼想到的,只能說看到這題就本能的就想到這個演算法。

我們對資料進行差分(就是前乙個數減後乙個數)。得到差分陣列cut。

0 1 2 -2

然後我們從左到右推,每次遇到乙個數 cut[i] 為正就讓cut [ i+k ]加上cut [ i ],cut [i] = 0。注意這裡的i+k必須小於等於n(這裡是5)。至於為什麼後面解釋。

然後變成了

0 0 0 -1(2)(最後乙個2是前面推來的,在位置n上,我們不需要這個數)

然後從右往左,每次遇到cut [ i ]為負數就讓cut [ i - k ] += cut [ i ],cut [ i ] = 0。注意i+k>=0。

然後變成

(-1) 0 0 0 0 (2)

這裡面的位置為1到4都是0,所以可以得出結果。

然後解釋一下我們為什麼做這種操作,***列一些變化過程。

3 3 2 0 2 cut:0 1 2 -2

3 3 3 1 2 cut:0 0 2 -1

3 3 3 3 4 cut:0 0 0 -1 (2)

3 3 4 4 4 cut:0 -1 0 0 (2)

4 4 4 4 4 cut:(-1) 0 0 0 0 (2)

懂了吧?因為一次操作的區間為k,所以差分陣列會變化的只有i和i+k或i和i-k。

假如i+k>n或者i-k<0,則是不可能的,我們也舉個例子。

k=2,3 4 4 4 4 , cut:-1 0 0 0

我們就無法把這個-1給清除掉,因為這涉及陣列外的數了。

下面給出**,速度還有很大的空間可以優化,但是沒必要

//

// created by acer on 2021/2/21.

//#include

using

namespace std;

#define int long long

const

int maxn =

2e5+10;

int num[maxn]

;int cut[maxn]

;signed

main()

for(

int j =

1; j <= n -1;

++j)

else}}

for(

int i = n -

1; i >=1;

--i)

cout << endl;*/

if(cut[i]

<0)

else

if(i - k ==0)

else

if(i - k <0)

}}int l;

for(l =

1; l <= n -1;

++l)

if(l != n)

cout <<-1

<< endl;

else

}}

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...