2019牛客暑期多校訓練營(第三場)F

2021-09-25 16:11:29 字數 2937 閱讀 8909

**

這個學期終於結束了,暑假就要來了。然而,作為大學畢業要求的一部分,你必須在假期期間參加一些社會服務。最後,你決定加入乙個志願者團體,在山上植樹。

為了簡化這個問題,讓我們用乙個n乘以n ×

\times

×n網格。讓我們給行編號1到n從上到下,給列編號1到n從左到右。用aij_

ij​表示第i行第j列的格仔的高度。

你的領導決定在山中的長方形區域種植樹木,並且該矩形中的任意兩個單元格之間的最大高度差不應超過m

請幫助你的領導計算盡可能多的細胞在這樣乙個矩形,以便他知道將種植多少棵樹。

輸入包含多個案例。輸入的第一行包含單個整數t(1≤t≤1000),即情況數。對於每一種情況,輸入的第一行包含兩個整數n(1≤n≤500)和m(0≤m≤105)。以下n行包含n個整數aij_

ij​​(1≤ i,j​≤10 5)。保證所有情況下n3之和不超過25⋅

\cdot

⋅ 107。

對於每種情況,都要列印乙個整數,即有效矩形中單元格的最大數量。

2

2 01 2

2 13 1

1 3 2

2 3 1

3 2 1

1

4

參考自官方題解

**

#include

#include

using namespace std;

const

int maxn =

505;

int m, n, t, a[maxn]

[maxn]

, i, j, w, k, ans;

int mn[maxn]

, mx[maxn]

;//第i到j列 最小 最大 的元素

int q1[maxn]

, q2[maxn]

, l1, r1, l2, r2;

//最小 最大單調棧

intmain()

}for

(i =

1; i <= n; i++

)for

(j = i; j <= n; j++)if

((j - i +1)

*n < ans)

continue

; l1 = l2 =

1, r1 = r2 =0;

for(k = w =

1; k <= n; k++)if

((j - i +1)

*(n - w +1)

break;if

(w <= k) ans =

max(ans,

(j - i +1)

*(k - w +1)

);}}

}printf

("%d\n"

, ans);}

return0;

}

邏輯結構一樣,但是會超時,目前還沒有找到原因

#include

#include

using namespace std;

const

int n =

(int)(

5e2+5)

;//const int inf = 0x3f3f3f;

int t,n,m;

int a[n]

[n];

int amin[n]

;//amin[k]表示當前上下界內第k列的最小值

int amax[n]

;int ans;

list<

int> hmin,hmax;

//最小值、最大值棧

void

solve()

for(

int j=i;j)//該情況最大都比已得結果小,不用往下計算了if(

(j - i +1)

* n < ans)

continue

;//這行和上面乙個for交換會出錯,想象為什麼

int l=

0,r=0;

//矩形左右邊界

hmin.

clear()

; hmax.

clear()

;for

(r=0

;r)//保證新加入的元素比棧頂元素大

hmin.

push_back

(r);

while

(!hmax.

empty()

&&amax[r]

>=amax[hmax.

back()

])//保證新加入的元素比棧頂元素小

hmax.

push_back

(r);

while

(l <= r && amax[hmax.

front()

]- amin[hmin.

front()

]> m)if(

(j - i +1)

*(n - l +1)

break

;//r加到最大其得到的面積也小於當前結果,退出本輪

if(l <= r) ans =

max(ans,

(j - i +1)

*(r - l +1)

);}}

}//cout("%d\n"

,ans);}

intmain()

solve()

;}return0;

}

本題又考驗了單調棧、單調佇列的運用,如果用的好,時間將降為o(n)

這個問題怎樣才能想到用單調佇列,是乙個難點

思考過程

2019牛客暑期多校訓練營(第三場)

目錄 b crazy binary string 思維 d big integer 數論 f planting trees 思維 單調佇列 h magic line 計算幾何 j lru management 模擬 題意 計算最長的01子串和子串行,其中01數量相同。分析 對於子串那麼直接將0製成 ...

牛客暑期多校訓練營B Boundary

給定n個點,然後確定乙個過原點的圓,要使這n個點盡可能多的存在與圓上,最後輸出最多的存在於圓上的點的個數 三點確定乙個圓,我們已知這個圓必定經過原點,所以再依次利用三點求圓心的公式列舉每兩個點與原點 三點不共線 確定的圓心,最後選擇確定次數最多的圓心構成的圓 include include incl...

2019牛客暑期多校訓練營(第三場) B題

題意 給你乙個長度為n的01字串,問該字串中01個數相等的最長子串和子串行分別是多少。分析 首先,大家要知道什麼是子串行,什麼是子串,子串行是不一定是連續的,它可以是原串中任意元素按照相對位置組成的序列,但是子串就不是了,子串一定是連續的,不可分割的按照絕對位置組成的序列。知道這個概念之後,大家可以...