51Nod 1279 扔盤子
阿新 • • 發佈:2018-12-24
有一口井,井的高度為N,每隔1個單位它的寬度有變化。現在從井口往下面扔圓盤,如果圓盤的寬度大於井在某個高度的寬度,則圓盤被卡住(恰好等於的話會下去)。
盤子有幾種命運:1、掉到井底。2、被卡住。3、落到別的盤子上方。
盤子的高度也是單位高度。給定井的寬度和每個盤子的寬度,求最終落到井內的盤子數量。
如圖井和盤子資訊如下:
井:5 6 4 3 6 2 3
盤子:2 3 5 2 4
最終有4個盤子落在井內。
收起
輸入
第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)
輸出
輸出最終落到井內的盤子數量。
輸入樣例
7 5
5
6
4
3
6
2
3
2
3
5
2
4
輸出樣例
4
思路:
想了很久,發現了下面一層不管比上面一層大多少都不影響判定。所以如果出現下一層比上一層大的情況,則直接將下一層等於上一層。然後從上到下就形成了個遞減序列,這是從下往上遍歷,找第一個比盤大或等於盤子寬度的層,這層就是盤子的落腳點。因為上面的轉化後都比下面的大。
程式碼如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int maxn=50005; int n,m; int w[maxn]; int d[maxn]; int ans=0; int main() { scanf("%d%d",&n,&m); w[0]=0x3f3f3f3f; for (int i=1;i<=n;i++) { scanf("%d",&w[i]); if(w[i]>w[i-1]) { w[i]=w[i-1]; } } for (int i=1;i<=m;i++) { scanf("%d",&d[i]); } for (int i=n,j=1;i>=1;i--,j++) { while (w[i]<d[j]&&i>=1) { i--; } if(i>=1&&w[i]>=d[j]) { ans++; } } printf("%d\n",ans); return 0; }