51nod-1379 扔盤子

題目:

有一口井,井的高度爲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

 

思路:

第一次思路是從第一個圓蓋開始往裏邊填,一直填到不能填,時間複雜度是O(N^2),提交上去超時,看了博客才知道要逆向考慮,首先分析可知,如果盤子可以落到n,那麼比n淺的深度的寬度必須都大於等於n位置的寬度,那麼我們可以預處理一下井,使得井從深往淺,寬度遞增。這樣,我們填圓蓋時可以直接從最底層開始填充,一直填到結束出結果,這樣的複雜度爲O(n)。

 

代碼:

#include<stdio.h>
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int a[50010]= {1000000010},sum=0,k=n;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i]>a[i-1])
            a[i]=a[i-1];
    }
    for(int i=1; i<=m; i++)
    {
        int x;
        scanf("%d",&x);
        for(;k>0;k--)
        {
            if(a[k]>=x)
            {
                k--;
                sum++;
                break;
            }
        }
    }
    printf("%d\n",sum);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章