• 集训


    WYT的刷子

    题目描述

    WYT有一把巨大的刷子,刷子的宽度为M米,现在WYT要使用这把大刷子去粉刷有N列的栅栏(每列宽度都为1米;每列的高度单位也为米,由输入数据给出).使用刷子的规则是:

    1. 与地面垂直,从栅栏的底部向上刷
    2. 每次刷的宽度为M米(当剩余栅栏宽度不够M米的话,刷子也可以使用,具体看样例2
    3. 对于连续的M列栅栏,刷子从底向上,刷到的高度只能到这M列栅栏的最低高度。

    WYT请你回答两个问题:

    1. 最少有多少个单位面积不能刷到(单位面积为1平米)
    2. 在满足第一问的条件下,最少刷几次?

       

    输入格式

    共两行:

    第一行两个整数NM

    第二行共N个整数,表示N列栅栏的高度

    输出格式

    一行,两个整数,分别为最少剩余的单位面积数量和最少刷的次数。

    样例输入1

    5 3

    5 3 4 4 5

    样例输出1

    3

    2

    样例输入2

    10 3

    3 3 3 3 3 3 3 3 3 3

    样例输出2

    0

    4样例输入3

    7 4

    1 2 3 4 3 2 1

    样例输出3

    4

    4

    样例1解释

    高度分别为 5 3 4 4 5 如上:

    黄色的方块表示共有3个单位面积没刷上

    绿色的数据范围与提示

    30%的数据:N<=10^3

    50%的数据:N<=10^5

    100%的数据:1<=N<=10^6, 1<=M<=10^6,N>=M, 每列栅栏的高度<=10^6.

    框和红色的框表示一共刷了两次

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=1e6+10;
     5 int a[maxn],r[maxn],l[maxn],mh[maxn],st[maxn],q[maxn];
     6 int main(){
     7     int n,m;
     8     long long sum=0;
     9     scanf("%d%d",&n,&m);
    10     for(int i=1;i<=n;i++){
    11        scanf("%d",&a[i]);
    12        sum+=a[i];
    13     }
    14     int head=0;
    15     int tail=-1;//这样初始化只是为了让a[1]进栈
    16     for(int i=1;i<=n;i++){
    17         while(head<=tail&&a[i]<a[st[tail]]){//当a[i]<a[栈顶]时栈顶不能全部向右延伸
    18              r[st[tail]]=i-st[tail];
    19              tail--;
    20         }
    21         st[++tail]=i;
    22     }
    23     while(tail>=0){//栈中其他出栈
    24        r[st[tail]]=n-st[tail]+1;
    25        tail--;
    26     }
    27    head=0;
    28     tail=-1;
    29     for(int i=n;i>=0;i--){
    30         while(head<=tail&&a[i]<a[q[tail]]){
    31             l[q[tail]]=q[tail]-i;
    32             tail--;
    33         }
    34         q[++tail]=i;
    35     }//左边界同上
    36     int flag[maxn];
    37     for(int i=1;i<=n;i++){
    38         if(r[i]+l[i]-1>=m) flag[i]=1;//记得-1,因为寻找左右边界时都加上了自己
    39     }
    40     for(int i=1;i<=n;i++){
    41         if(flag[i]==1){
    42             mh[i]=a[i];
    43         }
    44         else{
    45             mh[i]=mh[i-1];//不能写成mh[i]=a[i-1],因为可能第i-1也不能全部被刷玩
    46         }
    47     }
    48     for(int i=n;i>=1;i--){//从右边扫一遍
    49         if(flag[i]==0) mh[i]=max(mh[i],mh[i+1]);
    50         sum-=mh[i];
    51     }
    52     int k=2,ans=0;
    53     while(k<=n+1){//n+1保证全部都被扫到
    54          int cnt=1;
    55          while(k<=n+1&&mh[k]==mh[k-1]){
    56               cnt++;
    57               k++;
    58          }
    59          k++;
    60          ans+=cnt/m;
    61          if(cnt%m!=0) ans++;
    62     }
    63     printf("%lld
    %d",sum,ans);
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    2017年5月19日13:58:17 问题记录
    2017年5月17日20:14:29 rabbitmq 消费 异常信息无法处理 导致轮询
    2017年5月12日15:10:46 rabbitmq不支持非阻塞调用服务器
    2017年5月11日17:43:06 rabbitmq 消费者队列
    2017年5月10日16:11:28 定义所有问题
    MyBatis Plus 只插入只有自增id字段的表
    Centos 7 关闭报警音
    关于git项目切换远程提交路径和提交仓库
    IDEA通过git回滚到某个提交节点或某个版本
    IDEA使用@Autowired注解报错解决方案
  • 原文地址:https://www.cnblogs.com/HZOIDJ123/p/13227231.html
Copyright © 2020-2023  润新知