一、栈
1.介绍
2.总结
3.应用
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> a(n);
for(int i=0;i<n;i++){ //输入的其实就是栈的输出顺序
cin>>a[i]; // 5 6 4 1 3 2
}
//n个数的入栈顺序:1、2、3、4、5.。。n
// 5 6 4 1 3 2
stack<int>s;
int cur=1;
bool f=1;
for(int i=0;i< n;i++){
while( ( s.empty() || s.top()!=a[i] ) && cur <= n)
{
s.push(cur);
cur++;
}
if(s.empty() || s.top()!=a[i] ){
f=0;
break;
}else{
s.pop();
}
}
if(f){
cout<<"legal"<<endl;
}else{
cout<<"illegal"<<endl;
}
return 0;
}
二、递归
1.阶乘
2.斐波那契
3.递归函数
#include<cstdio>
using namespace std;
long long f(int x){
if(x<=0){
return 0;
}
if(x ==1){
return 1;
}
if( x>1 && x % 2 == 0){
return 3 * f( x / 2) - 1;
}
if(x > 1 && x % 2 == 1 ){
return 3*f( (x+1) / 2 ) -1 ;
}
}
int main(){
int x;
scanf("%d",&x);
printf("%lld\n",f(x));
}
4.汉诺塔
#include<iostream>
#include<stack>
using namespace std;
stack<int> s[3];//定义三个栈
void move(int x,int y){
int temp=s[x].top();
s[x].pop();
s[y].push(temp);
cout<< x<<"-->"<<y<<endl;
}
void hanoi(int A,int B,int C,int n)
{
if(n==1){ //边界条件
move(A,C);
return ;
}
hanoi(A,C,B,n-1);
move(A,C);
hanoi(B,A,C,n-1);
}
int main(){
int n;
cin>>n;
for(int i=n;i>=1;i--){
s[0].push(i);
}
hanoi(0,1,2,n);
while(!s[2].empty())
{
cout<<s[2].top()<<" ";
s[2].pop();
}
return 0;
}
5.汉诺塔升级
#include<iostream>
#include<stack>
using namespace std;
long long f[65],g[65];
stack<int> s[3];
/**
推测递推公式:
f[1]=1;
f[n] = f[n-1] + 1 + f[n-1];
就是 移动n-1个盘子的步数 + 移动一步 + 在移动n-1个盘子
消耗的体力:
g[n] = g[n-1] + n + g[n-1];
*/
int main()
{
int n;
cin>>n;
f[1]=1;
for(int i=2;i<=n;i++){
f[i]= 2* f[i-1] + 1;
}
g[1]=1;
for(int i=2;i<=n;i++){
g[i]= 2* g[i-1] + i;
}
cout<<f[n]<<" "<<g[n]<<endl;
}
三、栈和递归练习题
1. 猴子吃桃
#include<iostream>
using namespace std;
/**
递归函数:
f(n)/2 -1 =f(n-1)
f(n-1)为前一天吃完后剩下的桃子
是第 n-1 天在吃之前桃子的总数
f(n) = 2*( f(n-1) + 1 )
*/
int f(int x)
{
if(x ==1 )
{
return 1;
}
return 2*( f(x-1) + 1 );
}
int main()
{
int n;
cin >> n;
cout<< f(n) <<endl;
return 0;
}
2.重定义斐波那契数列
#include<iostream>
using namespace std;
int p;
int f(int n,int a,int b){
if(n==1 ||n==2){
return 1;
}else{
return ( (a* f(n-1,a,b) ) % p + (b* f(n-2,a,b ) )%p ) % p;
}
}
int main()
{
int n,a,b;
cin>>n>>a>>b>>p;
cout<<f(n,a,b);
return 0;
}
3.快速幂
#include<iostream>
using namespace std;
long long f(long long x,long long y,long long p)
{
if(y==0){
return 1%p;
}else if(y>0 && y%2==0){
long long temp=f(x,y/2,p);
return temp*temp%p;
}else{
long long temp=f(x,y/2,p);
return temp*temp*x%p;
}
}
int main(){
int t;
cin>>t;
long long x,y,p;
while(t--){
cin>>x>>y>>p;
cout<<f(x,y,p)<<endl;
}
return 0;
}
4.最少弹簧次数
#include<iostream>
#include<algorithm>
using namespace std;
int a[205],b[205];
int n;
int f(int x)
{
if(x>=n){
return 0;
}
return min( f(x+a[x]),f(x+b[x])) + 1;
}
int main(){
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=0;i<n;i++)
{
cin>>b[i];
}
cout<<f(0)<<endl;
return 0;
}
5.最大公约数
#include<iostream>
using namespace std;
int f(int x,int y)
{
if(y==0)
{
return x;
}else
{
return f(y,x%y);
}
}
int main()
{
int x,y;
cin>>x>>y;
cout<<f(x,y)<<endl;
return 0;
}
6.括号匹配
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
char s[50005];
stack<int> st;
int ans[50005];
int main(){
int len;
bool f=true;
scanf("%s",s);
len=strlen(s);
for(int i=0;i<len;i++){
if(s[i]=='('){
st.push(i+1);
}else{
if(!st.empty()){
ans[i+1]=st.top();
st.pop();
}else{
f=false;
break;
}
}
}
if(!st.empty()){
f=false;
}
if(!f){
printf("No\n");
}else{
printf("Yes\n");
for(int i=1;i<=len;i++){
if(ans[i]){
printf("%d %d\n",ans[i],i);
}
}
}
return 0;
}