51nod 1272 最大距離

2022-07-24 03:42:15 字數 2701 閱讀 3811

題目**:

給出乙個長度為n的整數陣列a,對於每乙個陣列元素,如果他後面存在大於等於該元素的數,則這兩個數可以組成一對。

每個元素和自己也可以組成一對。例如:,可以組成11對,如下(數字為下標):

(0,0), (0, 2), (1, 1), (1, 2), (1, 3), (1, 4), (2, 2), (3, 3), (3, 4), (4, 4), (5, 5)。其中(1, 4)是距離最大的一對,距離為3。

第1行:1個數n,表示陣列的長度(2 <= n <= 50000)。

第2 - n + 1行:每行1個數,對應陣列元素ai(1 <= ai <= 10^9)。

輸出最大距離。

653

6342

3

這道題發明了乙個方法(也可以用單調棧 / 單調佇列來做),我自己起了個名字叫做 「 字首賽梯法 」 。很好玩吧,但是是個有意義的名字

這個方法也不能叫做方法吧,但可以稱之為技巧。

能作為這兩個數中的前乙個數要滿足的要求:前面沒有小於他的

(我們把能滿足這個要求的所有數字都存到a陣列裡)

能作為這兩個數中的後乙個數要滿足的要求:後面沒有大於他的

(我們把能滿足這個要求的所有數字都存到b陣列裡)

相信大家讀題的時候也已經發現了,我們要找的是他後面所有比這個數大於或等於的數。

一邊輸入也可以一邊找出a陣列中存什麼數字好,輸入完了後我們可以從n-1 —> 0 在來一次迴圈找出b陣列裡的數

至於怎麼找呢?

我們可以記錄下a陣列裡上乙個數的下標,把 a[這個數] 和現在這個數進行比較,如果現在這個數小於上次存的那個數

a陣列裡多存乙個i(我往a陣列裡存的都是下標),上次那個數的下標變成這次的下標。

a陣列存數字的方法:

for(int i = 0;i < n;i++)

}

1、一邊輸入一邊存

2、prenum裡面記錄的是(上一次存進a陣列裡那個數的,在a陣列裡的)下標。

如果一開始還沒存數進去 或者 已經存了的那個數,卻發現這次的也符合題目的要求

3、如果符合上面敘述的情況,把下標(i)存進a裡面,a[prenum++] = i 

b陣列同理。

b陣列存數字的方法:

for(int i = n-1;i >= 0;i--)

}

1、從n-1開始迴圈。因為這次我們要從後往前找符合這個條件的:後面沒有大於他的

(我是從0開始輸入的,如果你從1開始的話最好把prenum和postnum都賦值為1,這樣你往a陣列和b陣列裡存數的時候就是從下標為1開始存了)

2、prenum裡面記錄的是(上一次存進b陣列裡那個數的,在b陣列裡的)下標。

如果一開始還沒存數進去 或者 已經存了的那個數,卻發現這次的也符合題目的要求

3、如果符合上面敘述的情況,把下標(i)存進b裡面, b[postnum++] = i

這時候,a陣列裡肯定是降序的,b陣列肯定也是降序的。大家自己思考一下這點。

現在開始講輸出

輸出照常來說我們都要把a陣列裡的數和b陣列裡的數一一進行對比才能肯定哪個就是答案

可是這裡我們用了乙個小技巧:

假設a陣列裡有3個數,b陣列裡有3個數,正常情況來說需要判斷9次,實際上這個**可能只需要判斷5次就出結果了。

而且正常情況還會tle(超出時間限制)

那麼我們這個不同尋常的技巧是什麼?

注意:a陣列裡肯定是降序的,b陣列肯定也是降序的

if(a陣列裡的數是小於b陣列裡的數的)else

在我的**中我為了輸出定義了兩個數

1、pre_idx 的意思是現在a陣列查到哪個數了,如果待會的答案是可以的,使a陣列往前乙個數就相當於pre_idx-1

2、post_idx 的意思是現在b陣列查到哪個數了,如果待會的答案不可以,使b陣列往後乙個數就相當於post_idx-1

long

long pre_idx = 0, post_idx = postnum -1

;for(;pre_idx < prenum && post_idx >= 0

;)else

}

輸出的話我也自己起了個名字:ab判斷法

是不是很生動:)

判斷ab兩個陣列哪個下標會變

#include#include

#include

using

namespace

std;

long

long n, a[50010], a[50010], b[50010

];long

long cnt_a=1, cnt_b=1

, ans, prenum, postnum;

intmain()

}for(int i = n-1;i >= 0;i--)

}long

long pre_idx = 0, post_idx = postnum -1

;

for(;pre_idx < prenum && post_idx >= 0

;)else

}cout

<< ans

}

51Nod 1272 最大距離

acm模版 方法有很多種,這裡介紹兩種寫法。第一種比較容易想到的寫法是將鍵值和下標封裝在結構體中進行排序,然後從尾部檢索一遍即可,複雜度o nlogn 第二種是使用單調棧優化,可以使複雜度低至o n one include include include using namespace std co...

51nod 1272 最大距離

codility 基準時間限制 1 秒 空間限制 131072 kb 分值 20 難度 3級演算法題 給出乙個長度為n的整數陣列a,對於每乙個陣列元素,如果他後面存在大於等於該元素的數,則這兩個數可以組成一對。每個元素和自己也可以組成一對。例如 可以組成11對,如下 數字為下標 0,0 0,2 1,...

51Nod1272 最大距離

給出乙個長度為n的整數陣列a,對於每乙個陣列元素,如果他後面存在大於等於該元素的數,則這兩個數可以組成一對。每個元素和自己也可以組成一對。例如 可以組成11對,如下 數字為下標 0,0 0,2 1,1 1,2 1,3 1,4 2,2 3,3 3,4 4,4 5,5 其中 1,4 是距離最大的一對,距...