51 nod 1279 扔盤子 思維好題)

2022-09-13 20:54:22 字數 1555 閱讀 8352

1279扔盤子

基準時間限制:1秒 空間限制:131072kb 分值: 10難度:2級演算法題

收藏關注

取消關注

有一口井,井的高度為n,每隔1個單位它的寬度有變化。現在從井口往下面扔圓盤,如果圓盤的寬度大於井在某個高度的寬度,則圓盤被卡住(恰好等於的話會下去)。

盤子有幾種命運:1、掉到井底。2、被卡住。3、落到別的盤子上方。

盤子的高度也是單位高度。給定井的寬度和每個盤子的寬度,求最終落到井內的盤子數量。

如圖井和盤子資訊如下:

井:5 6 4 3 6 2 3

盤子:2 3 5 2 4

最終有4個盤子落在井內。

本題由 @j**aman 翻譯。

input

第1行:2個數n, m中間用空格分隔,n為井的深度,m為盤子的數量(1 <= n, m <= 50000)。

第2 - n + 1行,每行1個數,對應井的寬度wi(1 <= wi <= 10^9)。

第n + 2 - n + m + 1行,每行1個數,對應盤子的寬度di(1 <= di <= 10^9)

output

輸出最終落到井內的盤子數量。

input示例

7 556

4362

3235

24

output示例

4

分析:將井的寬度等效轉換成乙個遞減的序列.若乙個盤子過不了第i高度的井口,那麼肯定過不了第i+1高度的井口,所以第i+1高度的井口可等效為a[i+1]=min(a[i+1],a[i]).

然後列舉盤子與井口寬度比較並更新井口區間即可.

並不一定要用二分,暴力列舉也可以的.

stl:

#include #include 

using

namespace

std;

intn,m;

int a[50005

];int

main()

int ans=0,now=n-1

;

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

}cout

}return0;

}

1 #include 2 #include 3

using

namespace

std;

4int

n,m;

5int a[50005];6

int p[50005];7

intmain()

818 reverse(a,a+n);

19int start=0,ans=0,flag=0;20

for(int i=0;i)

2132 cout

34return0;

35 }

暴力列舉:

51Nod 1279 扔盤子 思維 模擬

題意 有口井,往裡扔盤子,最多扔多少個 思路 如果比較高的地方井口比較小,那麼下面的再大也沒有用,只需要維護乙個單調減的陣列然後o n m 模擬即可 include include include include include include include include include inc...

51nod 1279 扔盤子(單調棧)

開始是直接從井口往裡扔,複雜度是o n 2 超時。然後呢,你會發現,如果井上邊的寬度小,下邊的寬度大,那麼下邊寬度多大都是沒用的,所以就讓他等於上邊寬度就好了。然後處理後這個井的寬度從上到下就是乙個非遞增的了,然後從下向上匹配,o n 還可以用單調棧預處理 include include const...

51Nod 1279 扔盤子 二分

這道題如果暴力走 o n 2 肯定超時 然後看資料5 10 4 時間1s 呃 o nlogn 一下是能過的 然後 在想我為什麼要o n 2 走 肯定會有重複的啊 那怎麼省略掉這些呢 很簡單 如果我這個圓盤往下掉 第一層的寬度小於第二層的寬度 那麼很明顯 第二層的寬度是沒有用處的 那麼有用的是什麼呢 ...