51Nod - 1279:扔盘子

   有一口井,井的高度为N,每隔1个单位它的宽度有变化。现在从井口往下面扔圆盘,如果圆盘的宽度大于井在某个高度的宽度,则圆盘被卡住(恰好等于的话会下去)。盘子有几种命运:1、掉到井底。2、被卡住。3、落到别的盘子上方。盘子的高度也是单位高度。给定井的宽度和每个盘子的宽度,求最终落到井内的盘子数量。
如图井和盘子信息如下:
这里写图片描述
井    :5 6 4 3 6 2 3
盘子:2 3 5 2 4
最终有4个盘子落在井内。
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
输出最终落到井内的盘子数量。
Sample Input
7 5
5
6
4
3
6
2
3
2
3
5
2
4
Sample Output
4

求井的有效宽度->得到从井底到井口的递增序列
因为盘子只有3种状态:放在井底,放在别的盘子上方和卡在井里,且盘子的顺序不能更改
即这个盘子放不进井里,则之后的盘子都放不进井
从井底开始遍历,能放下ans就自增,不能放下就继续遍历

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
ll h[50050], a[50050];
int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        scanf("%lld", &h[i]);
    for (int i = 0; i < m; i++)
        scanf("%lld", &a[i]);
    ll minn = h[0];
    for (int i = 1; i < n; i++)
        h[i] = minn = min(minn, h[i]); //,cout<<h[i]<<" "
    //        cout<<endl;
    int x = n - 1, ans = 0;
    for (int i = 0; i < m; i++) {
        if (x < 0)
            break;
        while (h[x] < a[i] && x > 0)
            x--;
        if (h[x] >= a[i])
            ans++;//cout<<a[i]<<" ",
        x--;
    }
    //    cout<<endl;
    cout << ans << endl;
    return 0;
}
阅读更多
相关热词
换一批

没有更多推荐了,返回首页