Caso 1: Si la pila solo se puede abrir una vez antes de cada pila:
Código de núcleo:
// v作为栈存放数据,res作为缓存,存放出栈的元素,打印的时候res从0到n,v从n到0
void DFS(vector<char>v,vector<char>res,int circle){
if(circle==length){
printres(res);
cout<<"*";
printstack(v);
cout<<endl;
return;
}
// 不把该输入pop
v.push_back(input[circle]);
DFS(v,res,circle+1);
// pop该输入
v.pop_back();
res.push_back(input[circle]);
DFS(v,res,circle+1);
}
La versión completa del código:
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
int length=0;
vector<char>input;
void printres(vector<char>v){
int i;
for(i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
}
void printstack(vector<char>v){
while(!v.empty()){
cout<<v.back()<<" ";
v.pop_back();
}
cout<<endl;
}
void DFS(vector<char>v,vector<char>res,int circle){
if(circle==length){
printres(res);
cout<<"*";
printstack(v);
cout<<endl;
return;
}
// 不把该输入pop
v.push_back(input[circle]);
DFS(v,res,circle+1);
// pop该输入
v.pop_back();
res.push_back(input[circle]);
DFS(v,res,circle+1);
}
int main() {
// freopen("test.txt","r+",stdin);
vector<char>v;
int i;
scanf("%d",&length);
char c;
for(i=0;i<length;i++){
cin>>c;
input.push_back(c);
}
vector<char>res;
DFS(v,res,0);
return 0;
}
/*
3
a b c
*/
Caso 2: si el número de pops es ilimitado
¿Cómo calcular cuántas combinaciones?
- Debido a que la pila está vacía al final, el número de 0 (emergente) y 1 (en la pila) debe ser el mismo.
- Si 0 es mayor que 1 en la cadena 0-1, debe haber un punto que satisfaga este punto y el punto anterior.
0的和==1的和-1
image.png
- Si 0 después de este punto se convierte en 1, y 1 se convierte en 0, entonces hay m + n 1, m + n + 2 0s, por lo que si el número total es 2N, puede haber C (N + 1,2N) especies.
- Entonces, la respuesta es que hay C (N, 2N) -C (N + 1,2N) combinaciones de N elementos.
Si N elementos pueden interrumpir el orden de apilamiento, habráN!*(C(N,2N)-C(N+1,2N))
¿Cómo codificarlo?
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int length=0;
void print(vector<char>v){
int i;
for(i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
}
// queue用来存放键盘输入,res用来存放pop时打印的输出序列,v用来作为栈使用(最后一次性打印)
void DFS(vector<char>v,vector<char>res,queue<char>q){
if(q.empty()){
// 当 q.empty()时打印res然后再打印v
print(res);
// 输出栈中元素
reverse(v.begin(),v.end());
// 栈要逆向输出
print(v);
cout<<endl;
return;
}
// pop栈v中元素然后放入res中,不需要消耗q
if(!v.empty()){
res.push_back(v.back());
v.pop_back();
// 继续递归
DFS(v,res,q);
// 恢复v和res的初始状态
v.push_back(res.back());
res.pop_back();
}
// 不把该输入pop,存放入栈中
if(!q.empty()){
v.push_back(q.front());
q.pop();
DFS(v,res,q);
}
}
int main() {
freopen("test.txt","r+",stdin);
vector<char>res;
queue<char>q;
vector<char>v;
int i;
scanf("%d",&length);
char c;
for(i=0;i<length;i++){
cin>>c;
q.push(c);
}
DFS(v,res,q);
return 0;
}
/*
3
a b c
*/
Otras lecturas:
Aplicación del problema del número Cattleya:
-
Hay un total de 2n puntos etiquetados como 1, 2, 3, 4, ..., 2n en la circunferencia. Estos 2n puntos se pueden emparejar para formar n cadenas, y el número de formas en que estas cadenas están desunidas es el número de Cattleya.
image.png
-
Una entrada para el parque de atracciones cuesta 1 yuan y una entrada por persona es limitada. Ahora hay 10 niños haciendo cola para comprar boletos, cinco de ellos solo tienen un billete de RMB 1 cada uno, y los otros cinco niños solo tienen un billete de RMB 2. El conductor no preparó ningún cambio. Pregunta: ¿Cuántos métodos de colas existen para que el conductor siempre pueda encontrar cambio?
-
A y B compiten en tenis de mesa. El resultado final es 20:20. Pregunte el número de situaciones de puntuación en las que A siempre está por delante de B durante el juego. Es decir, A siempre está por delante de B de 1 a 19 puntos, y el número de especies es Cattleya.
-
En un mapa de cuadrícula con Cn = n * n, el número de caminos de una esquina a otra sin cruzar la diagonal. Por ejemplo, los caminos en un mapa de cuadrícula de 4 × 4 son:
image.png