• 洛谷 P3434 [POI2006]KRA-The Disks 贪心


    题面

    题目链接

    P3434 [POI2006]KRA-The Disks

    题目描述

    一个框,告诉你每一层的宽度。

    向下丢给定宽度的木块。

    木块会停在卡住他的那一层之上,异或是已经存在的木块之上。

    询问丢的最后一个木块停在第几层。

    输入输出格式

    输入格式

    第一行两个整数 $ n $ 和 $ m (1 leq n, mleq 300 000) $ 表示水管包含的圆筒数以及盘子总数. 第二行给出 $ n $ 个整数 $ r_1, r_2,...,r_n ( 1 leq r_i leq 1 000 000 000) $ 表示水管从上到下所有圆筒的直径. 第三行给出 $ m $ 个整数 $ k_1, k_2,..., k_m ( 1leq k_j leq 1 000 000 000) $ 分别表示Johnny 依次扔下去的盘子直径

    输出格式

    一个整数输出最后一个盘子掉在了哪一层,如果盘子不能扔进水管,那么打印0

    输入输出样例

    输出样例

    7 3
    5 6 4 3 6 2 3
    3 2 5
    

    输出样例

    2
    

    说明

    【时空限制】

    1000ms,128MB

    思路

    首先要明确一个事实。如果上面一层比下面一层窄,那么实际上下层可用的面积和上一层是一样大的。所以像这样读入是肯定没有问题的。

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&h[i]);
        if(i!=1) h[i]=min(h[i],h[i-1]);
    }
    

    再模拟这个过程。第一个盘子肯定停留在从上往下最后宽度比他大的那一层,然后这个盘子的下面部分都没有用了。所以从后往前扫一遍就行了

    AC代码

    #include<bits/stdc++.h>
    const int maxn=300010;
    using namespace std;
    
    int n,m;
    int h[maxn];
    int np;
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&h[i]);
            if(i!=1) h[i]=min(h[i],h[i-1]);
        }
        np=n+1;
        for(int i=1,tmp;i<=m;i++)
        {
            scanf("%d",&tmp);
            np--; ///这里要注意。np是上一个盘子的位置,这一个盘子不能掉在np的位置了。
            while(h[np]<tmp && np>0) np--;
            if(np==0) break;
        }
        printf("%d",np);
        return 0;
    }
    
  • 相关阅读:
    了解 DICOM 基本协议与其相关
    C# PropertyInfo 反射实体部分字段
    ref(引用参数) 和 out(输出参数) 区别
    Linq Where Expression<Func<T,bool>> 查询条件
    随笔规范
    C# 集合分析
    C# 几种常用的数据类型
    关于 C# 方法参数的理解
    打算开始写博客了
    有趣的算法、逻辑面试题
  • 原文地址:https://www.cnblogs.com/Mercury04/p/9813003.html
Copyright © 2020-2023  润新知