zoukankan      html  css  js  c++  java
  • ACM/ICPC竞赛

    07篇 ACM/ICPC竞赛之STL--stack/queue

    stack()queue(队列)也是在程序设计中经常会用到的数据容器,STL为我们提供了方便的stack()queue(队列)的实现。

    准确地说,STL中的stackqueue不同于vectorlist等容器,而是对这些容器的重新包装。这里我们不去深入讨论STLstackqueue的实现细节,而是来了解一些他们的基本使用。

    1stack

    stack模板类的定义在<stack>头文件中。

    stack模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要的,在不指定容器类型时,默认的容器类型为deque

    定义stack对象的示例代码如下:

        stack<int> s1;

        stack<string> s2;

    stack的基本操作有:

        入栈,如例:s.push(x);

        出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。

        访问栈顶,如例:s.top()

        判断栈空,如例:s.empty(),当栈空时,返回true

        访问栈中的元素个数,如例:s.size()

    下面是用stringstack写的解题hduoj 1064--Parencoding的程序。

        

     1 #include <iostream>
     2 
     3     #include <string>
     4 
     5     #include <stack>
     6 
     7     using namespace std;
     8 
     9     main()
    10 
    11     {
    12 
    13         int n;
    14 
    15         cin >> n;
    16 
    17         for (int i=0; i<n; i++)
    18 
    19         {
    20 
    21             int m;
    22 
    23             cin >> m;
    24 
    25             string str;
    26 
    27             int leftpa = 0;
    28 
    29             for (int j=0; j<m; j++)  // 读入P编码,构造括号字符串
    30 
    31             {
    32 
    33                 int p;
    34 
    35                 cin >> p;
    36 
    37                 for (int k=0; k<p-leftpa; k++) str += '(';
    38 
    39                  str += ')';
    40 
    41                 leftpa = p;
    42 
    43             }
    44 
    45              stack<int> s;
    46 
    47             for ( string::iterator it=str.begin(); it!=str.end(); it++ )
    48 
    49             {   // 构造M编码
    50 
    51                 if (*it=='(')
    52 
    53                     s. push (1);
    54 
    55                 else
    56 
    57                 {
    58 
    59                     int p = s. top (); s. pop ();
    60 
    61                     cout << p << " ";
    62 
    63                     if (!s. empty ()) s. top () += p;
    64 
    65                 }
    66 
    67             }
    68 
    69             cout << endl;
    70 
    71         }
    72 
    73         return 1;
    74 
    75     }

    2queue

    queue模板类的定义在<queue>头文件中。

    stack模板类很相似,queue模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型。

    定义queue对象的示例代码如下:

        queue<int> q1;

        queue<double> q2;

    queue的基本操作有:

        入队,如例:q.push(x); x接到队列的末端。

        出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。

        访问队首元素,如例:q.front(),即最早被压入队列的元素。

        访问队尾元素,如例:q.back(),即最后被压入队列的元素。

        判断队列空,如例:q.empty(),当队列空时,返回true

        访问队列中的元素个数,如例:q.size()

    3priority_queue

    <queue>头文件中,还定义了另一个非常有用的模板类 priority_queue(优先队列)。优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。

    priority_queue模板类有三个模板参数,第一个是元素类型,第二个容器类型,第三个是比较算子。其中后两个都可以省略,默认容器为vector,默认算子为less,即小的往前排,大的往后排(出队时序列尾的元素出队)。

    定义priority_queue对象的示例代码如下:

        priority_queue<int> q1;

        priority_queue< pair<int, int> > q2;  // 注意在两个尖括号之间一定要留空格。

        priority_queue<int, vector<int>, greater<int> > q3; // 定义小的先出队

    priority_queue的基本操作与queue相同。

    初学者在使用priority_queue时,最困难的可能就是如何定义比较算子了。

    如果是基本数据类型,或已定义了比较运算符的类,可以直接用STLless算子和greater算子——默认为使用less算子,即小的往前排,大的先出队。

    如果要定义自己的比较算子,方法有多种,这里介绍其中的一种:重载比较运算符。优先队列试图将两个元素xy代入比较运算符(less算子,调用 x<y,对greater算子,调用x>y),若结果为真,则x排在y前面,y将先于x出队,反之,则将y排在x前面,x将先出队。

    看下面这个简单的示例:

        

     1 #include <iostream>
     2 
     3     #include <queue>
     4 
     5     using namespace std;
     6 
     7     class T
     8 
     9     {
    10 
    11     public:
    12 
    13         int x, y, z;
    14 
    15         T(int a, int b, int c):x(a), y(b), z(c)
    16 
    17         {
    18 
    19         }
    20 
    21     };
    22 
    23     bool operator < (const T &t1, const T &t2)
    24 
    25     {
    26 
    27         return t1.z < t2.z;  // 按照z的顺序来决定t1和t2的顺序
    28 
    29     }
    30 
    31     main()
    32 
    33     {
    34 
    35         priority_queue<T> q;
    36 
    37         q.push(T(4,4,3));
    38 
    39         q.push(T(2,2,5));
    40 
    41         q.push(T(1,5,4));
    42 
    43         q.push(T(3,3,6));
    44 
    45  
    46 
    47         while (!q.empty())
    48 
    49         {
    50 
    51             T t = q.top(); q.pop();
    52 
    53             cout << t.x << " " << t.y << " " << t.z << endl;
    54 
    55         }
    56 
    57         return 1;
    58 
    59     }
    60 
    61  
    62 
    63 输出结果为(注意是按照z的顺序从大到小出队的):
    64 
    65  
    66 
    67     3 3 6
    68 
    69     2 2 5
    70 
    71     1 5 4
    72 
    73     4 4 3
     1 再看一个按照z的顺序从小到大出队的例子:
     2 
     3  
     4 
     5     #include <iostream>
     6 
     7     #include <queue>
     8 
     9     using namespace std;
    10 
    11     class T
    12 
    13     {
    14 
    15         public:
    16 
    17         int x, y, z;
    18 
    19         T(int a, int b, int c):x(a), y(b), z(c)
    20 
    21         {
    22 
    23         }
    24 
    25     };
    26 
    27     bool operator > (const T &t1, const T &t2)
    28 
    29     {
    30 
    31         return t1.z > t2.z;
    32 
    33     }
    34 
    35     main()
    36 
    37     {
    38 
    39         priority_queue<T, vector<T>, greater<T> > q;
    40 
    41         q.push(T(4,4,3));
    42 
    43         q.push(T(2,2,5));
    44 
    45         q.push(T(1,5,4));
    46 
    47         q.push(T(3,3,6));
    48 
    49  
    50 
    51         while (!q.empty())
    52 
    53         {
    54 
    55             T t = q.top(); q.pop();
    56 
    57             cout << t.x << " " << t.y << " " << t.z << endl;
    58 
    59         }
    60 
    61         return 1;
    62 
    63     }
    64 
    65  
    66 
    67 输出结果为:
    68 
    69  
    70 
    71     4 4 3
    72 
    73     1 5 4
    74 
    75     2 2 5
    76 
    77     3 3 6

    如果我们把第一个例子中的比较运算符重载为:

       

    1  bool operator < (const T &t1, const T &t2)
    2 
    3     {
    4 
    5         return t1.z > t2.z;  // 按照z的顺序来决定t1和t2的顺序
    6 
    7     }

    则第一个例子的程序会得到和第二个例子的程序相同的输出结果。

    再回顾一下用优先队列实现的题hduoj 1067--Ugly Numbers的代码:

      

     1   #include <iostream>
     2 
     3     #include <queue>
     4 
     5     using namespace std;
     6 
     7     typedef pair<unsigned long int, int> node_type;
     8 
     9     main( int argc, char *argv[] )
    10 
    11     {
    12 
    13         unsigned long int result[1500];
    14 
    15         priority_queue< node_type, vector<node_type>, greater<node_type> > Q;
    16 
    17         Q.push( make_pair(1, 3) );
    18 
    19         for (int i=0; i<1500; i++)
    20 
    21         {
    22 
    23             node_type node = Q.top();
    24 
    25             Q.pop();
    26 
    27             switch(node.second)
    28 
    29             {
    30 
    31             case 3: Q.push( make_pair(node.first*2, 3) );
    32 
    33             case 2: Q.push( make_pair(node.first*3, 2) );
    34 
    35             case 1: Q.push( make_pair(node.first*5, 1) );
    36 
    37             }
    38 
    39             result[i] = node.first;
    40 
    41         }
    42 
    43         int n;
    44 
    45         cin >> n;
    46 
    47         while (n>0)
    48 
    49         {
    50 
    51             cout << result[n-1] << endl;
    52 
    53             cin >> n;
    54 
    55         }
    56 
    57         return 1;
    58 
    59     }
    60 
    61  

    未完待续!!!

     

     

     

  • 相关阅读:
    jsp mysql 配置线程池
    服务端 模拟 检测 攻击。。乱写
    硕思闪客精灵 7.2 破解版
    unity UnityAwe 插件
    smartfoxserver 2x 解决 Math NAN
    unity 断点下载
    java 监听文件目录修改
    wind7 64 setup appjs
    sfs2x 修改jvm 内存
    unity ngui 解决图层问题
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4480321.html
Copyright © 2011-2022 走看看