蓝桥备赛(14)- 栈和 stack

一、栈的概念

栈是一种只允许  在  一端 进行数据插入和删除操作的  线性表

生活中的案例 :  

如果定义了一个栈结构,那么 添加和删除元素只能在栈顶进行 。不能随意位置添加和删除元素,这是栈这个数据结构的特性,也是规定。

二、栈的模拟实现

2.1 创建

1 ) 本质上还是线性表 , 因此可以创建一个足够大的数组 , 充当栈结构 。

2 )定义一个变量 n , 用来记录栈中元素的个数 , 同时可以标记栈顶的位置 

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 1e5 + 10;

//栈
int stk[N];
int n; 
int main()
{
	
	return 0;
}

2.2 进栈

1) 这里依旧舍弃下标为 0 的位置,有效元素从 1 开始记录。
2 )进栈操作,那就把元素放在栈顶位置即可
时间复杂度:O(1)
本质上是顺序表里面的尾插
3 )这里有一个小BUG ,栈满了就不可以再继续进栈了
这里我们在调用函数的时候知道就好了 , 如果在工程中 , 就一定需要外加判断;这里是为了让我们了解栈的特性 。

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 1e5 + 10;

//栈
int stk[N];
int n; 

//入栈
void push(int x)
{
	stk[++n] = x;
}
 
 //遍历栈
 void print()
 {
 	for(int i = 1 ; i<= n ; i++)
 	{
 		cout << stk[i] << " ";
	 }
	 cout << endl;
  } 
int main()
{
	push(1);
	push(2);
	push(3);
	push(4);
	//1 2 3 4
	print();
	return 0;
}

2.3 出栈

1 )不需要真的删除元素,只需要将元素个数减 1 ,就相当于删除栈顶元素
2 )时间复杂度:O(1)
3 ) 类比顺序表的尾删
4 )这里有一个小BUG ,空栈不可删

//出栈
void pop()
{
  	n--;
} 

2.4 栈顶元素

查询栈顶元素。
因为栈特殊的规定,不支持遍历整个栈中的元素。因此,需要查找栈中元素的时候,只 能查找到栈顶元素。
时间复杂度:O(1)

//栈顶元素
int top()
{
	return stk[n];	
} 

2.5 判空

//判断栈是否为空
bool empty()
{
	return n == 0;
 } 

2.6 有效元素的个数

 //有效元素的个数
 int size()
 {
 	return n;
 }

2.7 所有测试代码

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 1e5 + 10;

//栈
int stk[N];
int n; 

//入栈
void push(int x)
{
	stk[++n] = x;
}
 
 //遍历栈
 void print()
 {
 	for(int i = 1 ; i<= n ; i++)
 	{
 		cout << stk[i] << " ";
	 }
	 cout << endl;
  } 
  
//出栈
void pop()
{
  	n--;
} 

//栈顶元素
int top()
{
	return stk[n];	
} 

//判断栈是否为空
bool empty()
{
	return n == 0;
 } 
 
 //有效元素的个数
 int size()
 {
 	return n;
 }
  
int main()
{
	push(1);
	push(2);
	push(3);
	push(4);
	//1 2 3 4
	print();
	while(!empty())
	{
		pop();
		print();
	}
	return 0;
}

三、stack

3.1 创建

stack<T> st;

T : 可以是任意数据类型

3.2 size/empty

1) size : 返回栈里实际元素个数

2)empty : 返回栈是否为空。

时间复杂度: O(1) 。

3.3 push/pop

1)push :进栈

2)pop :出栈

时间复杂度: O(1) 。

3.4 top

top :返回栈顶元素,但是不会删除栈顶元素
时间复杂度: O(1)

3.5 所有测试代码

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

stack<int> st;
int main()
{
	//1~10 进栈
	for(int i = 1;i<=10;i++)
	{
		st.push(i); 
	 } 
	 while(st.size() )
	 {
	 	cout << st.top() << " ";
	 	st.pop() ;
	 }
	return 0;
}

四 、 算法题

4.1 【模板】栈

B3614 【模板】栈 - 洛谷

#include <iostream>
#include <cstdio>
using namespace std;

const int N = 1e6 + 10;
typedef unsigned long long LL;

int top;
LL stk[N];
int main()
{
	int T;
	cin >> T;
	while(T--)
	{
		//清空栈
		top = 0;
		
		int n ; 
		cin >> n;
		while(n--)
		{
			string op;
			cin >> op;
			if(op == "push")//入栈
			{
				LL x;
				cin >> x;
				stk[++top] = x;
			 } 
			 else if(op == "pop")
			 {
			 	if(top == 0)
			 		cout << "Empty" << endl;
				else
					top--;
			 }
			 else if(op == "query")
			 {
			 	if(top == 0) cout << "Anguei!" << endl;
			 	else
			 		cout << stk[top] << endl;
			 }
			 else
			 {
			 	cout << top << endl;
			 }
		}
		 
	}
	return 0;
}

4.2 有效的括号

20. 有效的括号 - 力扣(LeetCode)

class Solution {
public:
    bool isValid(string s) {
        stack<char> st;
        for(auto ch: s)
        {
            if(ch == '(' || ch == '[' || ch == '{')
            {
                st.push(ch);
            }
            else
            {
                if(st.empty()) return false;
                char left = st.top();
                if(ch == ')' && left != '(') return false;
                if(ch == ']' && left != '[') return false;
                if(ch == '}' && left != '{') return false;
            
                st.pop();
            }
        }
        return st.empty();
    }
};

4.3 验证栈序列

P4387 【深基15.习9】验证栈序列 - 洛谷

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

const int N = 1e5 + 10;
int q,n;
int st1[N],st2[N];
int main()
{
	cin >> q;
	while(q--)
	{
		cin >> n;
		for(int i = 1;i <= n ; i++) 	cin >> st1[i]; 
		for(int i = 1; i <= n ; i++)	cin >> st2[i];
		
		stack<int> st;
		int j = 1 ;//标记poped的第一个元素的下标
		for(int i = 1;i<= n ; i++)
		{
			//进栈 
			st.push(st1[i]);
			//判断是否入栈 
			while(j <= n && st.size() && st2[j] == st.top())
			{
				st.pop();
				j++; 
		 	} 
		}
		if(st.empty()) cout << "Yes" << endl;
		else cout << "No" << endl;	
	}
	return 0;
}

4.4 后缀表达式

P1449 后缀表达式 - 洛谷

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

int main()
{
	stack<int> st;
	
	char ch;
	int num = 0;
	while(cin >> ch)
	{
		if(ch == '@') break;
		else if(ch == '.')
		{
			st.push(num);
			num = 0;
		}
		else if(ch >= '0' && ch <= '9')
		{
			num = num * 10 + ch -'0';
		}
		else
		{
			//操作符
			int b = st.top();st.pop();
			int a = st.top();st.pop();
			if(ch == '+') st.push(a+b); 
			else if(ch == '-') st.push(a-b); 
			else if(ch == '*') st.push(a*b); 
			else st.push(a/b); 
		}
	}
	cout << st.top() << endl;
	return 0;	
} 

4.5 括号序列

P1241 括号序列 - 洛谷

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

const int N = 110;
string s;
bool st[N] ; //标记是否成功匹配 
string ret; //返回的字符串 
stack<int> stk; //存储左括号的下标值 
int main()
{
	cin >> s;
	int n = s.size() ;
	for(int i = 0;i < n;i++)
	{
		if(s[i] == '(' || s[i] == '[') stk.push(i);
		else
		{
			//右操作符
			if(stk.empty()) continue;
			
			char ch = s[stk.top()];
			if((ch == '(' && s[i] == ')' )|| (ch == '[' && s[i] == ']'))
			{
				st[stk.top()] = true;
				st[i] = true;
				stk.pop();	
			}	
		} 
	}
	for(int i = 0;i < n ; i++)
	{
		char ch = s[i];
		if(st[i]) ret += ch;
		else
		{
			//不能匹配就需要添上相应的括号
			if(ch == '(')
			{
				ret += ch;
				ret += ')';	
			} 
			else if(ch == ')')
			{
				ret += '(';
				ret += ch;
			}
			else if(ch == '[')
			{
				ret += ch;
				ret += ']';
			}
			else if(ch == ']')
			{
				ret += '[';
				ret += ch;
			}
		}
	}
	cout << ret << endl;
	return 0;
}

关于卡牌蓝桥游戏开发或工具的相关信息如下: --- ### 方法一:了解“蓝桥杯”与卡牌类游戏的关系 蓝桥杯是一项面向全国高校学生的编程竞活动,通常涉及算法设计、程序编写等内容。虽然其本身并非直接针对游戏开发,但参者可以通过学习相关的开发技术来制作卡牌类游戏。例如,在比中可能会遇到的任务包括实现卡牌抽取逻辑、计算概率分布以及优化用户体验。 --- ### 方法二:选择适合的游戏开发引擎 对于卡牌类游戏的开发,可以考虑以下几种主流工具框架: 1. **Unity** Unity 是一款功能强大的跨平台游戏引擎,支持 2D 3D 游戏开发。它内置了丰富的资源商店,可以帮助开发者快速构建卡牌界面及动画效果。此外,Unity 提供 C# 编程语言的支持,便于初学者上手。 示例代码片段(创建一个简单的抽卡函数): ```csharp using UnityEngine; public class CardDraw : MonoBehaviour { private string[] cardDeck = { "Fire", "Water", "Earth", "Air" }; void DrawCard() { int randomIndex = Random.Range(0, cardDeck.Length); Debug.Log("You drew a " + cardDeck[randomIndex]); } } ``` 2. **Godot Engine** Godot 是另一款免费开源的游戏引擎,特别适合小型独立团队使用。它的脚本系统灵活易懂,能够满足轻量级卡牌游戏的需求。 3. **Construct** 如果希望避免复杂的编码过程,则可以选择 Construct 这样的可视化编辑器。尽管它更适合休闲小游戏,但对于入门级别的卡牌项目仍然适用。 --- ### 方法三:参考在线教程与社区资源 许多网站提供详细的指南帮助新手进入游戏开发领域。比如 GitHub 上有许多公开仓库分享完整的卡牌游戏源码;YouTube 视频也常有实操演示视频可供观看模仿。同时不要忽略 Stack Overflow 等问答站点上的技术支持贴子解答常见疑问。 --- ### 注意事项 确保所选的技术符合目标设的要求(如 iOS/Android/Desktop),并且评估个人技术水平是否匹配相应难度等级前再做决定。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值