• SDUT PTA 栈和队列


    7-1 进制转换

    输入十进制整数N和待转换的进制x(2、8、16),分别代表十进制N转换成二进制、八进制和十六进制,输出对应的结果。十六进制中A~F用大写字母表示。

    输入格式:

    输入两个整数N(十进制整数N)和x(x进制),中间用空格隔开。

    输出格式:

    输出对应的结果。

    输入样例:

    在这里给出一组输入。例如:

    123 2
    

    输出样例:

    在这里给出相应的输出。例如:

    1111011
    

    输入样例:

    在这里给出一组输入。例如:

    123 16
    

    输出样例:

    在这里给出相应的输出。例如:

    7B
    

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. typedef long long LL;
    4. const int eps = 1e-8;// 一个极小值
    5. const int N = 1e4 + 100;
    6. const int M = 3e3 + 100;
    7. const int INF = 0x3f3f3f3f;
    8. const LL LINF = 0x3f3f3f3f3f3f3f3f;
    9. #define PI acos(-1.0)
    10. stack<char> s;// stl的容器
    11. int main()
    12. {
    13. int n, r;
    14. cin >> n >> r;
    15. if(n == 0) cout << "0" << endl;
    16. if(r == 16){
    17. while(n){
    18. int x = n % r;
    19. if(x < 10) s.push(x + '0');// 将int型转换为char型,使其能够存入char类型的栈中
    20. else s.push(x - 10 + 'A');
    21. n /= r;
    22. }
    23. }
    24. else{
    25. while(n){
    26. int x = n % r;
    27. s.push(x + '0');// 栈的特点:先进后出
    28. n /= r;
    29. }
    30. }
    31. while(!s.empty()){
    32. cout << s.top();// 栈顶是最后进栈的数
    33. s.pop();
    34. }
    35. return 0;
    36. }

     **为了用stl容器偷懒我真的努力了23333

    7-2 中缀表达式转换为后缀表达式 

    所谓中缀表达式,指的是运算符处于操作数的中间(例:3 * ( 4 + 2 )),中缀表达式是人们常用的算术表示方法,但中缀表达式不容易被计算机解析,因为既要考虑运算符的优先级,还要考虑括号的处理。但中缀表达式仍被许多程序语言使用,因为它符合人们的普遍用法。后缀表达式,指的是不包含括号,运算符放在两个操作数的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,也不需要考虑括号)。

    给出一个中缀表达式,请将其转换为后缀表达式并输出。

    输入格式:

    只有一行,是一个长度不超过1000的字符串,表示一个中缀表达式。表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。运算符、操作数之间用一个空格分隔,数据保证输入的操作数中不会出现负数,保证除数不会为0。

    输出格式:

    输出对应的后缀表达式。运算符、操作数之间用一个空格分隔,但行尾无多余空格。

    输入样例:

    3 * ( 4 + 2 )
    

    输出样例:

    3 4 2 + *
    

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. string a;// 在c++里不能用gets了
    6. char s[20];
    7. getline(cin, a);
    8. int len = a.size(), f = 0, cnt = -1;
    9. for(int i = 0; i < len; i++){
    10. if(a[i] >= '0' && a[i] <= '9'){
    11. if(f) printf(" ");
    12. f = 1;
    13. while(a[i] >= '0' && a[i] <= '9'){
    14. printf("%c", a[i++]);// 遇到数字就输出
    15. }
    16. i--;// 返回去输出空格
    17. }
    18. else{
    19. if(a[i] == '(') s[++cnt] = a[i];// 遇左括号就“入栈”
    20. else if(a[i] == '*' || a[i] == '/'){
    21. while(s[cnt] == '*' || s[cnt] == '/' && cnt != -1){
    22. printf(" %c", s[cnt--]);
    23. }
    24. s[++cnt] = a[i];
    25. }
    26. else if(a[i] == ')'){
    27. while(s[cnt] != '('){
    28. printf(" %c", s[cnt--]);
    29. }// 不是左括号(可能是加or减)就输出
    30. cnt--;// 无论是否有输出都得出个栈~最后左括号会出栈
    31. }
    32. else if(a[i] == '+' || a[i] == '-'){
    33. while(s[cnt] != '(' && cnt != -1){
    34. printf(" %c", s[cnt--]);
    35. }
    36. s[++cnt] = a[i];
    37. }
    38. }
    39. }
    40. while(cnt != -1){
    41. printf(" %c", s[cnt--]);
    42. }
    43. return 0;
    44. }

    **这个 只限一位数字。。 

    7-3 后缀式求值

    我们人类习惯于书写“中缀式”,如 3 + 5 * 2 ,其值为13。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)

    而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +

    现在,请对输入的后缀式进行求值。

    输入格式:

    在一行中输入一个后缀式,运算数运算符之间用空格分隔,运算数长度不超过6位,运算符仅有+ - * / 四种。

    输出格式:

    在一行中输出后缀式的值,保留一位小数。

    输入样例:

    3 5.4 2.2 * +
    

    输出样例:

    14.9
    

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. char str[10];
    6. double st[100];
    7. int top = 0;
    8. while(~scanf("%s", str)){// 这是一个字符一个字符输入的~
    9. if(str[1] == '\0' && (str[0] == '+' || str[0] == '-' || str[0] == '*' || str[0] == '/')){
    10. double num1 = st[--top];
    11. double num2 = st[--top];
    12. double res;
    13. switch(str[0]){
    14. case '+':
    15. res = num2 + num1;
    16. st[top++] = res;
    17. break;
    18. case '-':
    19. res = num2 - num1;
    20. st[top++] = res;
    21. break;
    22. case '*':
    23. res = num2 * num1;
    24. st[top++] = res;
    25. break;
    26. case '/':
    27. res = num2 / num1;
    28. st[top++] = res;
    29. break;
    30. }
    31. }
    32. else{
    33. double num;
    34. sscanf(str, "%lf", &num);// 从str中取出double类型的元素
    35. st[top++] = num;
    36. }
    37. }
    38. printf("%.1lf", st[0]);
    39. return 0;
    40. }

    **sscanf有好多用法

    7-4 括号匹配

    给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。

    输入格式:

    输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。

    输出格式:

    如果括号配对,输出yes,否则输出no。

    输入样例1:

    sin(10+20)
    

    输出样例1:

    yes
    

    输入样例2:

    {[}]
    

    输出样例2:

    no
    

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. const int N = 1e3 + 100;
    4. int main()
    5. {
    6. string s;
    7. int top = 0;
    8. char str[N];
    9. getline(cin, s);
    10. int i = 0;
    11. int len = s.size();
    12. for(i = 0; i < len; i++){
    13. if(s[i] == '(' || s[i] == '[' || s[i] == '{'){
    14. str[++top] = s[i];
    15. }
    16. if(s[i] == ')' || s[i] == ']' || s[i] == '}'){
    17. if((str[top] == '(' && s[i] == ')') || (str[top] == '[' && s[i] == ']') || (str[top] == '{' && s[i] == '}')){
    18. top--;
    19. }
    20. else break;
    21. }
    22. }
    23. if(top == 0 && i == len) cout << "yes" << endl;
    24. else cout << "no" << endl;
    25. return 0;
    26. }

    7-5 出栈序列的合法性

    给定一个最大容量为 M 的堆栈,将 N 个数字按 1, 2, 3, ..., N 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 M=5、N=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。

    输入格式:

    输入第一行给出 3 个不超过 1000 的正整数:M(堆栈最大容量)、N(入栈元素个数)、K(待检查的出栈序列个数)。最后 K 行,每行给出 N 个数字的出栈序列。所有同行数字以空格间隔。

    输出格式:

    对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES,否则输出NO

    输入样例:

    1. 5 7 5
    2. 1 2 3 4 5 6 7
    3. 3 2 1 7 5 6 4
    4. 7 6 5 4 3 2 1
    5. 5 6 4 3 7 2 1
    6. 1 7 6 5 4 3 2

    输出样例:

    1. YES
    2. NO
    3. NO
    4. YES
    5. NO

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. const int N = 1e3 + 100;
    4. int main()
    5. {
    6. int m, n, k;
    7. int stackk[N];
    8. int top = 0;
    9. int inx1 = 1, inx2 = 1;
    10. int b[N];
    11. cin >> m >> n >> k;
    12. while(k--){
    13. int f = 1;
    14. inx1 = 1, inx2 = 1;
    15. top = 0;
    16. for(int i = 1; i <= n; i++){
    17. cin >> b[i];
    18. }
    19. while(1){// 这个的存在大概就是为了让后面的break起作用
    20. if(inx1 == b[inx2]){// 元素进栈后立马出栈的情况
    21. inx1++;
    22. inx2++;
    23. }
    24. else if(top != 0 && stackk[top - 1] == b[inx2]){
    25. top--;
    26. inx2++;
    27. }// 判断如果栈中有元素,然后栈顶元素也与此时的出栈序列元素相同,那么就继续出栈来判断
    28. else{
    29. if(inx1 > n) break;
    30. stackk[top] = inx1;
    31. top++;
    32. inx1++;
    33. if(top >= m){
    34. f = 0;
    35. break;
    36. }
    37. }
    38. }
    39. if(!f || top != 0) cout << "NO" << endl;
    40. else cout << "YES" << endl;
    41. }
    42. return 0;
    43. }

    7-6 行编辑器

    一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区。
    由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的。较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无效;
    如果发现当前键入的行内差错较多或难以补救,则可以键入一个退行符"@",以表示当前行中的字符均无效。
    如果已经在行首继续输入'#'符号无效。

    输入格式:

    输入一个多行的字符序列。但行字符总数(包含退格符和退行符)不大于250。

    输出格式:

    按照上述说明得到的输出。

    输入样例1:

    在这里给出一组输入。例如:

    whli##ilr#e(s#*s)
    

    输出样例1:

    在这里给出相应的输出。例如:

    while(*s)
    

    输入样例2:

    在这里给出一组输入。例如:

    outcha@putchar(*s=#++);
    

    输出样例2:

    在这里给出相应的输出。例如:

    putchar(*s++);
    

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. const int N = 1e2 + 100;
    4. int main()
    5. {
    6. int cnt = 0;
    7. char str[N];
    8. string s;
    9. while(getline(cin, s)){
    10. int i = 0;
    11. for(i = 0; i < s.size(); i++){
    12. if(s[i] == '#' && cnt == 0) continue;
    13. else if(s[i] == '#') cnt--;
    14. else if(s[i] == '@') cnt = 0;
    15. else str[cnt++] = s[i];
    16. }
    17. for(int j = 0; j < cnt; j++){
    18. cout << str[j];
    19. }
    20. }
    21. return 0;
    22. }

    7-7 银行业务队列简单模拟

    设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

    输入格式:

    输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。

    输出格式:

    按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。

    输入样例:

    8 2 1 3 9 4 11 13 15
    

    输出样例:

    1 3 2 9 11 4 13 15
    

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. queue<int>a, b;
    4. int main()
    5. {
    6. int n, x;
    7. cin >> n;
    8. for(int i = 0; i < n; i++){
    9. cin >> x;
    10. if(x % 2 != 0) a.push(x);
    11. else b.push(x);
    12. }
    13. int cnt = 0;
    14. while(!a.empty() || !b.empty()){
    15. if(!a.empty()){
    16. if(cnt > 0) cout << " ";
    17. cout << a.front();
    18. a.pop();
    19. cnt++;
    20. }
    21. if(!a.empty()){
    22. if(cnt > 0) cout << " ";
    23. cout << a.front();
    24. a.pop();
    25. cnt++;
    26. }
    27. // 因为A = 2B
    28. if(!b.empty()){
    29. if(cnt > 0) cout << " ";
    30. cout << b.front();
    31. b.pop();
    32. cnt++;
    33. }
    34. }
    35. return 0;
    36. }

    7-8 堆栈模拟队列

    设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。

    所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:

    • int IsFull(Stack S):判断堆栈S是否已满,返回1或0;
    • int IsEmpty (Stack S ):判断堆栈S是否为空,返回1或0;
    • void Push(Stack S, ElementType item ):将元素item压入堆栈S
    • ElementType Pop(Stack S ):删除并返回S的栈顶元素。

    实现队列的操作,即入队void AddQ(ElementType item)和出队ElementType DeleteQ()

    输入格式:

    输入首先给出两个正整数N1N2,表示堆栈S1S2的最大容量。随后给出一系列的队列操作:A item表示将item入列(这里假设item为整型数字);D表示出队操作;T表示输入结束。

    输出格式:

    对输入中的每个D操作,输出相应出队的数字,或者错误信息ERROR:Empty。如果入队操作无法执行,也需要输出ERROR:Full。每个输出占1行。

    输入样例:

    1. 3 2
    2. A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T

    输出样例:

    1. ERROR:Full
    2. 1
    3. ERROR:Full
    4. 2
    5. 3
    6. 4
    7. 7
    8. 8
    9. ERROR:Empty

    代码长度限制

    16 KB

    时间限制

    400 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. int n1, n2;
    6. char ch;
    7. cin >> n1 >> n2;
    8. if(n1 > n2) swap(n1, n2);
    9. stack<int> s1, s2;
    10. while(cin >> ch && ch != 'T'){
    11. if(ch == 'A'){
    12. int x;
    13. cin >> x;
    14. if(s1.size() < n1) s1.push(x);
    15. else if(s2.empty()){
    16. while(!s1.empty()){
    17. s2.push(s1.top());
    18. s1.pop();
    19. }
    20. s1.push(x);
    21. }
    22. else cout << "ERROR:Full\n";
    23. }
    24. else {
    25. if(!s2.empty()){
    26. cout << s2.top() << endl;
    27. s2.pop();
    28. }
    29. else if(!s1.empty()){
    30. while(!s1.empty()){
    31. s2.push(s1.top());
    32. s1.pop();
    33. }
    34. cout << s2.top() << endl;
    35. s2.pop();
    36. while(!s2.empty()){
    37. s1.push(s2.top());
    38. s2.pop();
    39. }
    40. }
    41. else cout << "ERROR:Empty" << endl;
    42. }
    43. }
    44. return 0;
    45. }

    /*
        栈的特点:后进先出
        队列的特点:先进先出
        在两个栈之间来回倒腾,以模拟队列
    */

    7-9 选数

    已知n个整数x1,x2,x3...xi,以及1个整数k(k 3+7+12=22,
    3+7+19=29,
    7+12+19=38,
    3+12+19=34,

    现在,要求你计算出和为素数共有多少种。

    例如上例,只有一种的和为素数:3+7+19=29

    输入格式:

    第一行两个空格隔开的整数 n,k(1≤n≤20,k 第二行n个整数,两数之间空格隔开(1≤xi≤1000000)

    输出格式:

    输出一个整数,表示种类数。

    输入样例:

    在这里给出一组输入。例如:

    1. 4 3
    2. 3 7 12 19

    输出样例:

    在这里给出相应的输出。例如:

    1
    

    代码长度限制

    16 KB

    时间限制

    1000 ms

    内存限制

    128 MB

    1. #include
    2. using namespace std;
    3. const int N = 25;
    4. int a[N], n, k, cnt;
    5. bool isPrime(int n)
    6. {
    7. for(int i = 2; i * i <= n; i++){
    8. if(n % i == 0) return 0;
    9. }
    10. return 1;
    11. }
    12. void dfs(int m, int sum, int x)// x表示现在已经选取了几个数
    13. {
    14. if(m == k){
    15. if(isPrime(sum))
    16. cnt++;
    17. return ;
    18. }
    19. for(int i = x; i < n; i++){
    20. dfs(m + 1, sum + a[i], i + 1);
    21. }
    22. return ;
    23. }
    24. int main()
    25. {
    26. cin >> n >> k;
    27. for(int i = 0; i < n; i++){
    28. cin >> a[i];
    29. }
    30. dfs(0, 0, 0);
    31. cout << cnt;
    32. return 0;
    33. }

    7-10 全排列

    Lc今天上课学会了数的全排列并且Lc觉得数的全排列很简单,但是直到Lc的同桌YooQ向他提出了一个问题,该问题的描述如下:我们知道n的全排列总共有n!个序列,例如2的全排列有两个序列{1,2}和{2,1},现在你要解决的问题是n的全排列的n!个序列中第m个序列是什么?(注意:n的全排列的n!个序列是按字典序由小到大排序的)

    输入格式:

    第一行为样例组数t(t≤1e5),接下来t行每行有一个整数n和m(1<=n<=20,1<=m<=n!)

    输出格式:

    输出t行,每行输出n的全排列的n!个序列中第m个序列,两相邻的数间有一空格,行末不得有多余空格。

    输入样例:

    在这里给出一组输入。例如:

    1. 2
    2. 1 1
    3. 3 6

    输出样例:

    在这里给出相应的输出。例如:

    1. 1
    2. 3 2 1

    代码长度限制

    16 KB

    时间限制

    1000 ms

    内存限制

    1. #include
    2. using namespace std;
    3. const int N = 25;
    4. int a[N];
    5. int main()
    6. {
    7. int t, n, m;
    8. cin >> t;
    9. while(t--){
    10. cin >> n >> m;
    11. for(int i = 0; i < n; i++){
    12. a[i] = i + 1;// !!!
    13. }
    14. if(m == 1){
    15. for(int i = 0; i < n - 1; i++){
    16. cout << a[i] << " ";
    17. }
    18. cout << a[n - 1] << endl;
    19. }
    20. else{
    21. int cnt = 2;
    22. while(next_permutation(a, a + n)){
    23. if(cnt == m){
    24. for(int i = 0; i < n - 1; i++){
    25. cout << a[i] << " ";
    26. }
    27. cout << a[n - 1] << endl;
    28. break;
    29. }
    30. cnt++;
    31. }
    32. }
    33. }
    34. return 0;
    35. }

    /*
        将1~n存到一个数组里,聪明!!
    */

    7-11 输出全排列

    请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。

    输入格式:

    输入给出正整数n(<10)。

    输出格式:

    输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1​,a2​,⋯,an​排在序列b1​,b2​,⋯,bn​之前,如果存在k使得a1​=b1​,⋯,ak​=bk​ 并且 ak+1​

    输入样例:

    3
    

    输出样例:

    1. 123
    2. 132
    3. 213
    4. 231
    5. 312
    6. 321

    代码长度限制

    16 KB

    时间限制

    3500 ms

    内存限制

    64 MB

    1. #include
    2. using namespace std;
    3. int n, a[30];
    4. bool st[30];
    5. void dfs(int x){
    6. if(x == n){
    7. for(int i = 0; i < n; i++){
    8. cout << a[i];
    9. }
    10. cout << endl;
    11. return ;
    12. }
    13. for(int i = 1; i <= n; i++){
    14. if(!st[i]){
    15. a[x] = i;
    16. st[i] = 1;
    17. dfs(x + 1);
    18. st[i] = 0;
    19. }
    20. }
    21. return ;
    22. }
    23. int main()
    24. {
    25. cin >> n;
    26. dfs(0);
    27. return 0;
    28. }

  • 相关阅读:
    价格从9.9到几万元,凭票入场的VR元宇宙到底是什么体验?
    1013 Battle Over Cities
    风控建模二、特征工程---通用
    任意文件下载(读取)
    华为OD机试 - 热点网站统计 - 逻辑分析(Java 2023 B卷 100分)
    go语言并发实战——日志收集系统(七) etcd的介绍与简单使用
    作为一个测试工程师,爆火的“养了个羊”你知道哪些Bug吗?来看这里~
    【数据结构与算法】之深入解析“安排邮筒”的求解思路与算法示例
    赌上了绩效,赢了公司CTO,我要搭DevOps平台!
    香港ATA怎么办理
  • 原文地址:https://blog.csdn.net/qq_62846665/article/details/126803254