信息学奥赛第十七节 —— 栈与队列(stack、queue)

栈 —— stack
  • 一个先进后出(First In Last Out)的数据结构。
  • 或者说是一个后进先出(Last In First Out)的数据结构。

什么是先进后出?比如如果给定入栈顺序为1、2、3、4,那么,出栈顺序可能是1、2、3、4或者2、1、3、4。(也可能有其他的出栈顺序)

栈的常用函数
  • push() —— 向栈顶增加一个元素
  • pop() —— 删除栈顶元素
  • top() —— 取出栈顶元素
  • size() —— 栈中元素的个数
  • empty() —— 判断栈是否为空
栈的基本操作
#include 
#include 
using  namespace std;

int main()
{
    stack<int> stk;//初始化
    stk.push(10); stk.push(20); stk.push(30);//插入元素
    stk.push(40); stk.push(50);
    
    cout << stk.size() << endl;//5
    cout << stk.top() << endl;//50
    stk.pop();
    cout << stk.size() << endl;//4
    cout << stk.top() << endl;//40
    
    while (!stk.empty())//如果栈不空
    {
        cout << stk.top() << " ";
        stk.pop();
    }
    return 0;
}
练习(原题链接)

题目描述

十进制整数N和其他D(D的值为2、8、16)进制数的转换是计算机实现计算的基本问题,其解决方法很多,其中一个简单算法基于下列原理:N = (N div d)×d + N mod d (其中:div 为整除运算,mod 为求余运算)。简单来说,就是除D取余,然后倒过来得到D进制的数。
例如:
(1348)10 = (10101000100)2
(1348)10 = (2504)8
(1000)10 = (3E8)16
(请注意:转16进制时,用A代表余数10,B代表余数11……)
假设现要编制一个满足下列要求的程序:对于输入的任意一个非负十进制整数(n<=1,000,000,000),打印输出与其等值的D进制数。

输入

有两个整数N和D,N表示要转换的十进制非负整数,D代表要转换的进制(2、8或16)

输出

N进制转D进制的结果

样例输入

1348 2

样例输出

10101000100

解题思路:进制转换 —— 除基取余,逆序输出。另外特别注意一下:

  • 十进制与十六进制之间的转换涉及A、B、C、D、E、F。
  • 0的二进制、十六进制还是0。

AC代码

#include 
#include 
#include 
#include 

using  namespace std;

int main()
{
    stack<string> stk;//初始化
    int n,d; cin >> n >> d;
    
    if (n == 0) { cout << 0 << endl; return 0; }//0的其他进制为0
    
    while (n)//n不为0即可循环
    {
        int yushu = n % d;
        
        //特判十六进制
        if (d == 16 && yushu >= 10)
        {
            string str;
            if (yushu == 10) {str = 'A'; stk.push(str); n /= d;continue;}
            if (yushu == 11) {str = 'B'; stk.push(str); n /= d;continue;}
            if (yushu == 12) {str = 'C'; stk.push(str); n /= d;continue;}
            if (yushu == 13) {str = 'D'; stk.push(str); n /= d;continue;}
            if (yushu == 14) {str = 'E'; stk.push(str); n /= d;continue;}
            if (yushu == 15) {str = 'F'; stk.push(str); n /= d;continue;}
        }
        
        stk.push(to_string(yushu));
        n /= d;
    }
    
    while (!stk.empty())
    {
        cout << stk.top();
        stk.pop();
    }
    return 0;
}
括号匹配(原题链接)

题目描述

输入一个由()[]四种符号构成的字符串。判断其中的括号是否匹配,是,就输出yes,否则输出no。
比如:输入“([])”、“([()])”、“[((()))]”、“()[][][]”这几个字符串(双引号内部的内容),我们都算是匹配的。
再比如:输入“([)”、“([)]”、“([(]))”这几个字符串,我们都认为是不匹配的。

输入

一个由()[]四种符号构成的字符串

输出

如果匹配,请输出yes,如果不匹配,请输出no

样例输入

([])

样例输出

yes

解题思路:栈的经典应用,遇到左括号则入栈,遇到右括号且与栈顶元素匹配的时候,则出栈。
AC代码

#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    stack<char> stk; string s;
    getline(cin,s);
    
    for (int i = 0;i < s.size();i++)
    {
        if (s[i] == '[' || s[i] == '(') stk.push(s[i]);
        else if (s[i] == ']' && stk.top() == '[') stk.pop();
        else if (s[i] == ')' && stk.top() == '(') stk.pop();
    }
    
    if (stk.empty()) cout << "yes" << endl;
    else cout << "no" << endl;
    return 0;
}
队列 —— queue
  • 一个先进先出(First In First Out)的数据结构。
队列的常用函数
  • push() —— 向队尾增加一个元素
  • pop() —— 删除队头元素
  • front() —— 取出队头元素
  • back() —— 取出队头元素
队列的基本操作
#include 
#include 

using namespace std;

int main()
{
    queue<int> q;
    q.push(10); q.push(20); q.push(30);//10 20 30
    
    cout << q.front() << " " << q.back() << endl;//10 30
    q.pop();//出队
    cout << q.front() << endl;//20
    return 0;
}
队列的练习

题目描述

课代表SW由于工作失误被扣了奖学金,所以他不得不去某家饭店打工,饭店很火爆,经常没有位置,所以不得不叫号。
他管理叫号软件,一天他不小心把叫号软件的程序删除了,他感觉他完蛋了, 正准备跑路,善良的你不忍心他丢工作你能帮他重新写一个叫号软件吗?
软件有三个指令:
END为结束程序
PUSH NAME 为新来了一个名字叫做NAME的人排队,NAME的长度小于等于10,且NAME没有重复。
POP为如果有人在排队则输出当前队列中来的最早的人的名字并将其从队列里删除,如果队列没有人输出“EMPTY”(没有引号)

输入

只有一组测试数据
但是输入可能有若干行(保证不超过100000),每行一个命令:
PUSH NAME(NAME没有空格)
POP
END
其中,END命令只会在最后一行出现,并且保证有END
输入END命令后立刻结束程序

输出

针对每个POP命令输出一行,如果有人在排队则输出当前队列中来的最早的人的名字并将其从队列里删除 否则 输出“EMPTY”(没有引号)

样例输入

PUSH LZX
PUSH CQW
POP
PUSH SW
POP
POP
POP
END

样例输出

LZX
CQW
SW
EMPTY

解题思路:模拟过程即可
AC代码

#include 
#include 
#include 
#include 

using namespace std;

int main()
{
    queue<string> q;
    string s; 
    
    while (cin >> s)
    {
        if (s == "END") return 0;
        else if (s == "PUSH") 
        {
            string name; cin >> name; 
            q.push(name);
        }
        else if (s == "POP" && !q.empty())
        {
            cout << q.front() << endl;
            q.pop();
        }
        else if (s == "POP" && q.empty()) cout << "EMPTY" << endl;
    }
    return 0;
}

你可能感兴趣的:(信息学奥赛,c++,数据结构,算法)