zoukankan      html  css  js  c++  java
  • 【STL】栈+队列+优先队列(详)+ 拯救行动题解

    一、栈

          栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

        说通俗一点,就是一种有口无肛门的数据结构 咳咳...是一种满足“后进先出”规则的数据结构。有PUSH和POP两种操作。PUSH:把元素压入栈顶 POP:把元素从栈顶弹出

    栈定义在头文件<stack>中,用“stack<int> s”申明一个栈

    ↑_↑以上的都非常基础

    二、队列

          队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
          说通俗一点,就是一种有口有肛门的 咳咳...是符合“先进先出”原则的公平队列。
    队列定义在头文件<queue>中,用“queue<int> q”申明一个队列,用push(),pop()进行入队出队,front()取队首元素,但不删除√
    ↑_↑以上的还是非常基础
     
    三、优先队列
      在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。
      优先队列定义在头文件<queue>中,用“priority_queue<int> q”申明一个队列用push(),pop()进行入队出队,top()取队首元素,但不删除√ empty()队列是否为空
    用优先队列是时候我们必须先对每一个元素定义一个优先级,这样就需要重载运算符。
    比如,我们要定义一个“个位数大的优先级小”的优先队列可以这么写↓_↓
    /*
    定义一个结构体cmp,重载“()”运算符
    用“priority_queue<int, vector<int>, cmp> q”定义 
    */
    struct cmp
    {
        bool operator() (const int a, const int b)//a的优先值小于b返回true 
        const
        {
            return a % 10 > b % 10;
        }
    };

    如果要定义“越小的整数优先值越大”的优先队列,可以直接用这个:priority_queue<int, vector<int>, grater<int> >q

    然后有一道题↓_↓

    openjudge-4980:拯救行动

    描述

    公主被恶人抓走,被关押在牢房的某个地方。牢房用N*M (N, M <= 200)的矩阵来表示。矩阵中的每项可以代表道路(@)、墙壁(#)、和守卫(x)。 
    英勇的骑士(r)决定孤身一人去拯救公主(a)。我们假设拯救成功的表示是“骑士到达了公主所在的位置”。由于在通往公主所在位置的道路中可能遇到守卫,骑士一旦遇到守卫,必须杀死守卫才能继续前进。 
    现假设骑士可以向上、下、左、右四个方向移动,每移动一个位置需要1个单位时间,杀死一个守卫需要花费额外的1个单位时间。同时假设骑士足够强壮,有能力杀死所有的守卫。

    给定牢房矩阵,公主、骑士和守卫在矩阵中的位置,请你计算拯救行动成功需要花费最短时间。

    输入

    第一行为一个整数S,表示输入的数据的组数(多组输入)
    随后有S组数据,每组数据按如下格式输入 
    1、两个整数代表N和M, (N, M <= 200). 
    2、随后N行,每行有M个字符。"@"代表道路,"a"代表公主,"r"代表骑士,"x"代表守卫, "#"代表墙壁。

    输出

    如果拯救行动成功,输出一个整数,表示行动的最短时间。
    如果不可能成功,输出"Impossible"

    样例输入

    2
    7 8
    #@#####@
    #@a#@@r@
    #@@#x@@@
    @@#@@#@#
    #@@@##@@
    @#@@@@@@
    @@@@@@@@ 
    13 40
    @x@@##x@#x@x#xxxx##@#x@x@@#x#@#x#@@x@#@x
    xx###x@x#@@##xx@@@#@x@@#x@xxx@@#x@#x@@x@
    #@x#@x#x#@@##@@x#@xx#xxx@@x##@@@#@x@@x@x
    @##x@@@x#xx#@@#xxxx#@@x@x@#@x@@@x@#@#x@#
    @#xxxxx##@@x##x@xxx@@#x@x####@@@x#x##@#@
    #xxx#@#x##xxxx@@#xx@@@x@xxx#@#xxx@x#####
    #x@xxxx#@x@@@@##@x#xx#xxx@#xx#@#####x#@x
    xx##@#@x##x##x#@x#@a#xx@##@#@##xx@#@@x@x
    x#x#@x@#x#@##@xrx@x#xxxx@##x##xx#@#x@xx@
    #x@@#@###x##x@x#@@#@@x@x@@xx@@@@##@@x@@x
    x#xx@x###@xxx#@#x#@@###@#@##@x#@x@#@@#@@
    #@#x@x#x#x###@x@@xxx####x@x##@x####xx#@x
    #x#@x#x######@@#x@#xxxx#xx@@@#xx#x#####@

    样例输出

    13
    7

    拿到这道题以后可以发现是一个很简单的广搜,以时间为优先级,代码如下↓_↓
    #include<stdio.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    int n, m;
    int dx[4] = {1,-1,0,0},
        dy[4] = {0,0,1,-1};
    char map[201][201];
    bool flag;
    struct node//重载运算符,以时间为优先级 
    {
        int x, y, step;
        friend bool operator < ( node a, node b)
        {
            return a.step > b.step;
        }
    }www, mmm;
    priority_queue<node> q;
    int main()
    {
        int i, j, s;
        int sx, sy;
        scanf("%d", &s);
        while(s--)
        {
            while(!q.empty())q.pop();//注意!!一定要清空队列,这里写错调了一个下午的我...机房出现野生崩溃饼... 
            scanf("%d%d", &n, &m);
            for(i = 1; i <= n; i++)
            {
                for(j = 1; j <= m; j++)
                {
                    cin>>map[i][j];//不要问我为什么用cin→_→,我只是懒 
                    if(map[i][j] == 'r'){sx = i; sy = j;}
                }
            }            
            www.x = sx; www.y = sy; www.step = 0; map[sx][sy] = '#';
            q.push(www);
            flag = 0;
            while(!q.empty())//队列不为空 
            {
                www = q.top();//取队首元素 
                q.pop();//弹出队首元素 
                for(i = 0; i <= 3; i++)
                {
                    mmm.x = www.x+dx[i];
                    mmm.y = www.y+dy[i];
                    mmm.step = www.step+1;
                    if(mmm.x<1||mmm.y<1||mmm.x>n||mmm.y>m) continue;
                    if(map[mmm.x][mmm.y] == '#') continue;
                    if(map[mmm.x][mmm.y] == '@') {q.push(mmm);}//元素入队 
                    if(map[mmm.x][mmm.y] == 'x') {mmm.step++; q.push(mmm);}
                    if(map[mmm.x][mmm.y] == 'a') {printf("%d
    ", mmm.step); flag = 1; break;}
                    map[mmm.x][mmm.y] = '#';
                }
                if(flag) break;
            }
            if(!flag) printf("Impossible
    ");
        }
        return 0;
    }

    优先队列的基本用法完结~(≧▽≦)/~啦啦啦

  • 相关阅读:
    DHTML【11】--DOM
    sql 查询强制使用HASH连接性能测试比较
    Winform开发框架之读卡器和条码扫描枪的数据接收处理
    DevExpress的XtraReport和微软RDLC报表的使用和对比
    sql server日期时间转字符串
    C#在线更新程序[下载程序、解压缩程序、控制台程序]
    C# 定时器事件(设置时间间隔,间歇性执行某一函数,控制台程序)
    用C#用C#实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码实现窗体在规定时间弹出,例如:10:00.弹出后关闭。并在5分钟后再次弹出。5次后停止。最好有具体代码
    C#多线程学习之(五)使用定时器进行多线程的自动管理
    C# 文件与目录的基本操作(System.IO)
  • 原文地址:https://www.cnblogs.com/A-S-KirigiriKyoko/p/6060483.html
Copyright © 2011-2022 走看看