这套队列堆栈专题试卷做的我很心累,我感觉我开学的蓝桥杯比赛很悬,我现在就是非常后悔,非常非常后悔,嗐,没有抓紧时间刷题。⊙﹏⊙
悟已往之不谏,知来者之可追。好好刷题,不当炮灰!(ง •_•)ง
1、力扣(LeetCode)仅仅反转字母(15分)
原题链接
给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
示例 1:
输入:"ab-cd"
输出:"dc-ba"
示例 2:
输入:"a-bC-dEf-ghIj"
输出:"j-Ih-gfE-dCba"
示例 3:
输入:"Test1ng-Leet=code-Q!"
输出:"Qedo1ct-eeLg=ntse-T!"
提示:
S.length <= 100
33 <= S[i].ASCIIcode <= 122
S 中不包含 \ or "
不太熟悉力扣的提交方式,好像是只需补充函数,主函数不需要写,评判机会自动调用自定义函数。1w点暴击,简单面试题对我来说也不简单。。
题解链接
题解代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
string reverseOnlyLetters(string S) {
stack<char> s;
for(int i = 0; i < S.length(); i++)
{
if(isalpha(S[i]))
{
s.push(S[i]);
}
}
string ans;
for(int i = 0; i < S.length(); i++)
{
if(isalpha(S[i]))
{
ans += s.top();
s.pop();
}
else ans += S[i];
}
return ans;
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
string str;
getline(cin,str);
Solution s;
cout << s.reverseOnlyLetters(str) << endl;
return 0;
} 2.蓝桥杯 算法提高 队列操作(15分)
原题链接
问题描述
队列操作题。根据输入的操作命令,操作队列(1)入队、(2)出队并输出、(3)计算队中元素个数并输出。
输入格式
第一行一个数字N。下面N行,每行第一个数字为操作命令(1)入队、(2)出队并输出、(3)计算队中元素个数并输出。
输出格式
若干行每行显示一个2或3命令的输出结果。注意:2.出队命令可能会出现空队出队(下溢),请输出“no”,并退出。
样例输入
7 1 19 1 56 2 3 2 3 2
样例输出
19 1 56 0 no
数据规模和约定
1<=N<=50
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
queue<int> q;
int n;
cin >> n;
for(int i = 0;i<n;i++){
int k;
cin >> k;
if(k==1){
int m;
cin >> m;
q.push(m);
continue;
}else if(k==2){
if(!q.empty()){
cout << q.front() <<endl;
q.pop();
}else{
printf("no\n");
return 0;
}
continue;
}else{
cout << q.size() << endl;
}
}
} 3.C语言网 问题 1733: 堆栈的使用(15分)
原题链接
题目描述
堆栈是一种基本的数据结构。堆栈具有两种基本操作方式,push 和 pop。Push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出。现在我们就来验证一下堆栈的使用。
输入
对于每组测试数据,第一行是一个正整数 n,0<n<=10000(n=0 结束)。而后的 n行,每行的第一个字符可能是'P’或者'O’或者'A’;如果是'P’,后面还会跟着一个整数,表示把这个数据压入堆栈;如果是'O’,表示将栈顶的值pop 出来,如果堆栈中没有元素时,忽略本次操作;如果是'A’,表示询问当前栈顶的值,如果当时栈为空,则输出'E'。堆栈开始为空。
输出
对于每组测试数据,根据其中的命令字符来处理堆栈;并对所有的'A’操作,输出当时栈顶的值,每个占据一行,如果当时栈为空,则输出'E’。当每组测试数据完成后,输出一个空行。
样例输入
5 P 75 O O P 60 A 7 A O P 73 P 49 A O P 3 0
样例输出
60 E 49
这题我拉低了正确率,提交了很多次,出现了很多种错误,最后一种错误是格式错误,也没找到问题在哪,嗐,我太难了,好累啊啊啊啊啊啊啊啊
大佬的AC代码如下:
#include <bits/stdc++.h>
using namespace std;
#define Up(i,a,b) for(int i = a; i < b; i++)
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n;
while(cin >> n && n)
{
stack<int> s;
while(n--)
{
char ch;
cin >> ch;
if(ch == 'P')
{
int _;
cin >> _;
s.push(_);
}
else if(ch == 'O')
{
if(!s.empty()) s.pop();
else continue;
}
else if(ch == 'A')
{
if(!s.empty()) cout << s.top() << endl;
else cout << "E" << endl;
}
}
cout << endl;
}
return 0;
} 4、团体程序设计天梯赛-练习集 倒数第N个字符串(15分)
原题链接
给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当
L 为 3 时,序列为 { aaa, aab, aac, ..., aaz, aba, abb, ..., abz, ..., zzz
}。这个序列的倒数第27个字符串就是 zyz。对于任意给定的 L,本题要求你给出对应序列倒数第 N 个字符串。
输入格式:
输入在一行中给出两个正整数 L(2 ≤ L ≤ 6)和 N(≤1e5)。
输出格式:
在一行中输出对应序列倒数第 N 个字符串。题目保证这个字符串是存在的。
输入样例:
3 7417
输出样例:
pat
这题真的毫无思绪,大佬曰:这题实际上是进制转换,把L位数看成L个由26进制组成的数字,则最后一个数字的十进制表示为pow(26,L)-1,倒数N个数的十进制表示为pow(26,L)-N。这里用到了“后进先出”的栈,从pow(26,L)-N开始递减,把每个数字推入栈中,最后在栈顶的元素一定会是pow(26,L)-1,然后把所求的结果转换成26进制还原即可。若还原成26进制时位数不足L个,则需要在前面补上'a'。
题解链接
题解代码如下
#include <bits/stdc++.h>
using namespace std;
int main()
{
int L,N;
cin >> L >> N;
stack<int> s; //利用栈的“先进先出”
int num = pow(26,L)-N;
while(num)
{
s.push(num%26);
num /= 26;
}
for(int i = 0; i < L-s.size(); i++) //补a
{
cout << "a";
}
while(!s.empty()) //***大甩卖
{
cout << (char)('a' + s.top());
s.pop();
}
return 0;
} 5、PAT (Basic Level) Practice 1009 说反话 (20分)
原题链接
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80
的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1
个空格分开,输入保证句子末尾没有多余的空格。
输出格式:
每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
string str;
stack<string> st;
while(cin >> str){
st.push(str);
}
int cnt = 0;
while(!st.empty()){
if(!cnt){
cout << st.top();
cnt++;
}else{
cout << " " <<st.top();
}
st.pop();
}
} 6、PAT (Basic Level) Practice 1069 微博转发抽奖 (20分)
原题链接
小明 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包。请你编写程序帮助他确定中奖名单。
输入格式:
输入第一行给出三个正整数 M(≤ 1000)、N 和 S,分别是转发的总量、小明决定的中奖间隔、以及第一位中奖者的序号(编号从 1
开始)。随后 M 行,顺序给出转发微博的网友的昵称(不超过 20 个字符、不包含空格回车的非空字符串)。
注意:可能有人转发多次,但不能中奖多次。所以如果处于当前中奖位置的网友已经中过奖,则跳过他顺次取下一位。
输出格式:
按照输入的顺序输出中奖名单,每个昵称占一行。如果没有人中奖,则输出 Keep going...。
输入样例 1:
9 3 2 Imgonnawin! PickMe PickMeMeMeee LookHere Imgonnawin! TryAgainAgain TryAgainAgain Imgonnawin! TryAgainAgain
输出样例 1:
PickMe Imgonnawin! TryAgainAgain
输入样例 2:
2 3 5 Imgonnawin! PickMe
输出样例 2:
Keep going...
这题又不会处理,只知道要用队列,却不知如何实现,大佬曰:建立一个字符串队列queue用来存入中奖者的昵称,建立一个中奖者名单map,这个操作看上去是重复的,写到后面才会发现这两者的用处。立一个flag用来记录是否有人中奖,true为没人中奖。用for循环遍历,如果这是中奖者,先判断他在不在map里,若不在map里,就把他放入map同时入队,若在map里,就跳过他顺次取下一位(S++;continue)。每次抽完中奖者之后,中奖序号需要加上一个中奖间隔。最后把队列从队首开始根据“先进先出”的规则进行输出。如果flag依然为真,说明没人中奖,输出"Keep going..."
题解链接
题解代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int M,N,S; //M为转发的总量,N为小明决定的中奖间隔,S是第一位中奖者的序号
cin >> M >> N >> S;
queue<string> q; //字符串型队列
map<string, int> m;
bool flag = true; //flag用来记录是否有人中奖,true为没人中奖
for (int i = 1; i <= M; i++)
{
string temp;
cin >> temp;
if(i==S) //中奖者
{
flag = false;
if(m[temp]==0)
{
m[temp]++;
q.push(temp);
}
else
{
S++;
continue;
}
S += N;
}
}
while(!q.empty()) //***大甩卖
{
cout << q.front() << endl;
q.pop();
}
if(flag)
{
cout << "Keep going..." << endl;
}
return 0;
} 
京公网安备 11010502036488号