20200308递归总结

1.逆波兰表达式
【题目描述】
逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * /四个。
【输入】
输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。
【输出】
输出为一行,表达式的值。
可直接用printf("%f\n", v)输出表达式的值v。
【输入样例】

    • 11.0 12.0 + 24.0 35.0
      【输出样例】
      1357.000000
#include <iostream>
#include<algorithm>
#include<cmath>
#include<bits/stdc++.h>
using namespace std;
char ch[10005];
double nbl()
{
    cin>>ch;
    switch(ch[0])
    {
        case '+':return nbl()+nbl();
        case '-':return nbl()-nbl();
        case '*':return nbl()*nbl();
        case '/':return nbl()/nbl();
        default:return atof(ch);
    }
}
int main()
{
    cout<<fixed<<setprecision(6)<<nbl()<<endl;
    return 0;
}

2.Pell数列
【题目描述】
Pell数列
a1,a2,a3,…的定义是这样的,a1=1,a2=2,…,an=2an−1+an−2(n>2)a1=1,a2=2,…,an=2an−1+an−2(n>2)。
给出一个正整数 k,要求Pell数列的第 k项模上 32767是多少。
【输入】
第1行是测试数据的组数 n,后面跟着 nn行输入。每组测试数据占 1行,包括一个正整数k(1≤k<1000000)。
【输出】
n行,每行输出对应一个输入。输出应是一个非负整数。
【输入样例】
2
1
8
【输出样例】
1
408

#include<iostream>
using namespace std;
int n;
long long  s[1000005]={0};
int pell(int n)
{
    if(s[n]==0)
    {
        if(n==1) return s[n]=1;
        else if(n==2) return s[n]=2;
        else return s[n]=(2*pell(n-1)+pell(n-2))%32767;
    }
    else return s[n];
}
int main()
{
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        cin>>n;
        cout<<pell(n)<<endl;
    }
    return 0;
}

3.全排列
【题目描述】
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有‘a’ <‘b’ < … <‘y’<‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
【输入】
只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
【输出】
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。
【输入样例】
abc
【输出样例】
abc
acb
bac
bca
cab
cba

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
string str,ch[1000];
int s=0;
void Perm(int k,int m)
{
    if(m==k)
    {
        ch[s]=str;
        s++;
    }
    else
        for(int j=k;j<=m;j++)
        {
            swap(str[j],str[k]);
            Perm(k+1,m);
            swap(str[j],str[k]);
        }
}
int main()
{
    cin>>str;
    int len=str.length();
    Perm(0,len-1);
    sort(ch,ch+s);
    for(int i=0;i<s;i++)
        cout<<ch[i]<<endl;
    return 0;
}

4.括号匹配问题(运用栈)
【题目描述】
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用" " , " ? " 100 " "标注,不能匹配的右括号用"?"标注。 【输入】 输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。 【输出】 对每组输出数据,输出两行,第一行包含原始输入字符,第二行由" ","?“和空格组成,”$“和”?"表示与之对应的左括号和右括号不能匹配。
【输入样例】
((ABCD(x)
)(rttyy())sss)(
【输出样例】
((ABCD(x)
$$
)(rttyy())sss)(
? ?$

#include<iostream>
#include<cstring>
#include<string>
#include<stack>
using namespace std;
char str1[101],str2[101];
stack<int> ST;
int main()
{
    while(cin>>str1)
    {
        int len=strlen(str1);
        for(int i=0;i<len;i++)
        {
            if(str1[i]=='(')
            {
                ST.push(i);
                str2[i]=' ';
            }
            else if(str1[i]==')')
            {
                if(!ST.empty())
                {
                    ST.pop();
                    str2[i]=' ';
                }
                else str2[i]='?';
            }
            else str2[i]=' ';
        }
        while(!ST.empty())
        {
            str2[ST.top()]='$';
            ST.pop();
        }
        str2[len]='\0';
        cout<<str1<<endl<<str2<<endl;
    }
    return 0;
}

5.汉诺塔问题
【题目描述】
约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到中间的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面。
这是一个著名的问题,几乎所有的教材上都有这个问题。由于条件是一次只能移动一个盘,且不允许大盘放在小盘上面,所以64个盘的移动次数是:18,446,744,073,709,551,615
这是一个天文数字,若每一微秒可能计算(并不输出)一次移动,那么也需要几乎一百万年。我们仅能找出问题的解决方法并解决较小N值时的汉诺塔,但很难用计~算机解决64层的汉诺塔。
假定圆盘从小到大编号为1, 2, …
【输入】
输入为一个整数(小于20)后面跟三个单字符字符串。
整数为盘子的数目,后三个字符表示三个杆子的编号。
【输出】
输出每一步移动盘子的记录。一次移动一行。
每次移动的记录为例如 a->3->b 的形式,即把编号为3的盘子从a杆移至b杆。
【输入样例】
2 a b c
【输出样例】
a->1->c
a->2->b
c->1->b

#include<iostream>
#include<cstdio>
using namespace std;
int n;
void move(int n,char a,char c,char b)
{
    if(n==0) return;
    move(n-1,a,b,c);
    printf("%c->%d->%c\n",a,n,c);
    move(n-1,b,c,a);
}
int main()
{
    char o,p,q;
    cin>>n>>o>>p>>q;
    move(n,o,p,q);
    return 0;
}

6.2的幂次方表示
【题目描述】
任何一个正整数都可以用2的幂次方表示。例如:
137=27+23+20
同时约定方次用括号来表示,即ab可表示为a(b)。由此可知,137可表示为:
2(7)+2(3)+2(0)
进一步:7=22+2+20(21用2表示)
3=2+20
所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:
1315=210+28+25+2+1
所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
【输入】
一个正整数n(n≤20000)。
【输出】
一行,符合约定的n的0,2表示(在表示中不能有空格)。
【输入样例】
137
【输出样例】
2(2(2)+2+2(0))+2(2+2(0))+2(0)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a[20];
int n;
void mcf(int n){
    if(n==0)
        return;
    int i;
    for(i=0;i<=20;i++)
    {
        if(n<a[i])                 
            break;
    }
    i--;
    if(i==0)
        cout<<"2(0)";
    else if(i==1)
        cout<<"2";
    else if(i>1)
    {
        cout<<"2(";
        mcf(i);
        cout<<")";
    }
    if(n!=a[i])
    {
        cout<<"+";
        mcf(n-a[i]);
    }
}
int main(){
    long long num=1;
    for(int i=0;i<=20;i++){
        a[i]=num;
        num*=2;
    }
    cin>>n;
    mcf(n);
}
发布了8 篇原创文章 · 获赞 12 · 访问量 183

猜你喜欢

转载自blog.csdn.net/weixin_46434074/article/details/104730107
今日推荐