• Hdu 3410 【单调队列】.cpp


    题意:

      给出一个数组,问你对于第i个数,从最后一个比它大的数到它之间比它小的数中最大的那个数的下标,以及它右边到第一个比它大的数中比它小的数中最大的那一个数的下标<下标从1开始>。

      eg:5 2 4 3 1

        l    0 0 2 0 0        对5来说左边比它小的数没有,所以是0。对2来说左边比它小的数没有,所以是0。对4来说左边比它小的数是2,所以下标是2。

        r   3 0 4 5 0         对5来说右边比它小的数中最大的是4,是第3个,所以答案是3。对2来说右边比它小的数是1,但是4比2大,所以无法到达1,所以答案是0。对于4,右边比它小的数中最大一个3的下标是4,所以答案是4。

    思路:

      单调队列。

      先从左向右维护一个单调队列,然后在维护过程中最后一个从队列中剔除掉的即右边比它小的数中最大的那一个。

      单调队列中的值是下标值。

      从右向左再维护一个单调队列就可以求出另一个值。

     

    Tips:

      nothing..

    Code: 

     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int MAXN = 50010;
     7 
     8 int main()
     9 {
    10     freopen("in.txt", "r", stdin);
    11     int iCase, n, ic = 1;
    12     int arr[MAXN], que[MAXN];
    13     int rear, front;
    14     int l[MAXN], r[MAXN];
    15     bool flag;
    16     scanf("%d", &iCase);
    17     while (iCase--) {
    18         arr[0] = 0;
    19         memset(que, 0, sizeof(que));
    20 
    21         scanf("%d", &n);
    22         for (int i = 1; i <= n; ++i)
    23             scanf("%d", &arr[i]);
    24 
    25         front = 0, rear = -1;
    26         for (int i = 1; i <= n; ++i) {
    27             flag = false;
    28             while (front <= rear && arr[que[rear]] < arr[i]) {
    29                 flag = true;
    30                 rear--;
    31             }
    32             if (flag) l[i] = que[rear+1];
    33             else l[i] = 0;
    34             que[++rear] = i;
    35         }
    36 
    37         front = 0, rear = -1;
    38         for (int i = n; i >= 1; --i) {
    39             flag = false;
    40             while (front <= rear && arr[que[rear]] < arr[i]) {
    41                 flag = true;
    42                 rear--;
    43             }
    44             if (flag) r[i] = que[rear+1];
    45             else r[i] = 0;
    46             que[++rear] = i;
    47         }
    48 
    49         printf("Case %d:
    ", ic++);
    50         for (int i = 1; i <= n; ++i) {
    51             printf("%d %d
    ", l[i], r[i]);
    52         }
    53     }
    54     return 0;
    55 }
    View Code

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3410

  • 相关阅读:
    (转)描述线程与进程的区别?
    Python学习笔记:ceil、floor、round、int取整
    Python学习笔记:SQL中group_concat分组合并操作实现
    Python学习笔记:pd.rank排序
    函数声明
    Dictionary 介绍
    Tuple介绍
    List介绍
    DataGridView 如何退出 编辑状态
    C#实现打印与打印预览功能
  • 原文地址:https://www.cnblogs.com/Griselda/p/3217105.html
Copyright © 2020-2023  润新知