北大mooc《程序设计与算法二 算法基础》学习笔记---------递归

1:

 

思路分析:

 

 

 

我的实现如下:

#include <iostream> 
using namespace std;
double exp_value();
double elem_value();
double yz_value(); 

int main()
{
    printf("%0.2f\n",exp_value());
    
    return 0;
}


double exp_value()
{
    double result=elem_value();
    while(true)
    {
        char c =cin.peek();
        if(c=='+' || c=='-')
        {
            cin.get();
            double value=elem_value();
            if(c=='+' )
                result+=value;
            else
                result-=value;
        }
        else
            return result;
    }    
}
double elem_value()
{
    double result =yz_value();
    while(true)
    {
        char c =cin.peek();
        if(c=='*' || c=='/')
        {
            cin.get();
            double value=yz_value();
            if(c=='*' )
                result*=value;
            else
                result/=value;
        }
        else
            return result;
    }    
}
double yz_value()
{
    double result=0;
    double intg=0;
    double decm=0;
    double d=10.0;
    bool flag=true;
    char c =cin.peek();
    
    if(c=='(')
        {
            cin.get();
            result= exp_value();
            cin.get();
        //    cout<<result<<endl;
        }
    else
        {
            while(isdigit(c)||c=='.')
            {
                if(c=='.')
                {
                    flag=false;
                    cin.get();
                    c =cin.peek();    
                }
                if(flag)
                {
                    cin.get();
                    intg=intg*10+c-'0';
                    c =cin.peek();
                }
                else
                {
                    cin.get();
                    decm=decm+(c-'0')/d;
                    d*=10.0;
                    c =cin.peek();
                }    
                    
            }    
            result=decm+intg;    
        }
        
        return result;
}

TIPS:

  -> cin.get :从输入流中取出一个字符,若为EOF,则返回-1.

  ->cin.peek: 从输入流中向前看一个字符,若为EOF,则返回-1.

    两者的返回值都为int。

  ->把思路理清,图像画出来后,代码真他妈容易写,可这个分析好难!

 

2:

 

 

#include <iostream> 
using namespace std;

/*********************
*没盘子为空的情况,就相当于,每个盘子放一个苹果后,剩下的随便在这些盘子中放置的个数。
*有盘子为空的情况,就相当于,至少有一个盘子为空,这样问题规模就缩小了。 *k:苹果数 *i:盘子数 **********************
*/ int f(int k,int i) { if(i>k) return f(k,k); if(k==0)//苹果等于0,代表上一级函数的k==i,于是正好每一个盘子一个苹果。 return 1; if(i==1)//只剩一个盘子了,当然只有一种放法 return 1; return f(k,i-1)+f(k-i,i); } int main() { int n; cin>>n; int a,b; while(n--) { cin>>a>>b; cout<<f(a,b)<<endl; } return 0; }

 

3:

#include <iostream> 
#include <cmath>
using namespace std;
//注意判断浮点数是否相等时,不能用==,而要用两数之差的绝对值是否小于一个相当小的数。
#define EPS 1e-6 bool isZero(double a) { return fabs(a)<EPS?true:false; } bool count24(double a[],int n) { if(n==1) { return fabs(a[0]-24)<EPS?true:false; } else { double b[5]; int m; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) { m=0; for(int k=0;k<n;k++ )//把没选择的数放入临时数组中 { if(k!=i&&k!=j) b[m++]=a[k]; } b[m]=a[i]+a[j];//以下为分别判断+ - * /四种情况。注意减法和除法各有两种。且除数不能为0. //cout<<m<<endl; if(count24(b,m+1)) return true; b[m]=a[i]-a[j]; if(count24(b,m+1)) return true; b[m]=a[j]-a[i]; if(count24(b,m+1)) return true; b[m]=a[i]*a[j]; if(count24(b,m+1)) return true; if(!isZero(a[j])) { b[m]=a[i]/a[j]; if(count24(b,m+1)) return true; } if(!isZero(a[i])) { b[m]=a[j]/a[i]; if(count24(b,m+1)) return true; } } } return false; } int main() { double b[5]; int num=0; while(true) { cin>>b[0]>>b[1]>>b[2]>>b[3]; num=0; for(int i=0;i<4;i++) { if(b[i]==0) num++; } if(num==4) break; if(count24(b,4)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }

 

 4:

  Boolean Expressions

    题目链接:http://cxsjsxmooc.openjudge.cn/2019t2summer3/001/

    

#include <iostream> 
#include <cmath>
using namespace std;

char str[110];
int num;
int now;

bool exp();
bool elem()
{
    bool value;
    
    char c=str[now];

        if(c=='F'||c=='V')
        {
            //cout<<"3"<<endl;
            now++;
            value= (c=='F'?false:true);
        }
            
        else if(c=='!')
        {
            now++;
            value= !elem();
        }
        else if(c=='(')
        {
            //cout<<"1"<<endl;
            now++;
            value=exp();
            now++;
        }
    return value;
}
bool exp()
{    
    //cout<<"2"<<endl;
    bool value = elem();
    char c=str[now];
    while(true)
    {
        if(c=='&')
        {
            now++;
            bool right=elem();
            value= right && value;
        }
        else if(c=='|')
        {
            now++;
            bool right=elem();
            value= right || value;
        }
        else
            break;
            
        c=str[now];
    }
    return value;
}
int kk;
void input()
{
    num=0;
    now=0;
    int c =cin.get();
    while(c!='\n')
    {
        while(c==' ')
            c =cin.get();
        str[num++]=c;
        if(c==EOF)
            break;
        c =cin.get();
    }
    //cout<<++kk<<endl;
}
int main()
{
    
            //freopen("D:\\360MoveData\\Users\\CQcoming\\Desktop\\in (4).txt","r",stdin);
        
        int i=0;
            while(str[now]!=EOF)
            {
                input();
                
                bool flag =exp();
                printf("Expression %d: ",++i);
                if(flag)
                    printf("V\n");
                else
                    printf("F\n");
            }

    //char c=cin.peek();
//    cout<<(int)c<<endl;
    
    return 0;
}

tips:

  -> 注意,题目中说明了文件输入,所以终止条件为EOF。

  -> 这题跟那个表达式求值的解法几乎一样,画出定义图后,再写代码就很快了。

 

5:

#include <iostream> 
#include <cmath>
using namespace std;


int f(int k,int i)//k 苹果  i 盘子 
{
    if(k<i)
        return f(k,k);
    if(k==0)
        return 1;
    if(i==1)
        return 1;    
    return f(k,i-1)+f(k-i,i);
}

int main()
{
    //freopen("D:\\360MoveData\\Users\\CQcoming\\Desktop\\in (7).txt","r",stdin);
    int n,num;
    int c;
    int k=0;
    do
    {
        cin>>n;
        cin.get();//由于\n还在输入流中,需要过滤到\n,下一个才有可能是EOF。
        c=cin.peek();
        num=0;
        for(int i=1;i<=n;i++)//放在一个盘子到n个盘子的情况,累加起来,就是答案。
        {
            num+=f(n-i,i);//确定了盘子个数后,每个盘子里面肯定得有苹果,所以相当于f(n-i,i)。
} cout<<num<<endl; }while(c!=EOF); return 0; }

tips:

  这题只需要在放苹果问题解法的基础上,稍加修改就行了。

posted @ 2019-08-01 03:53  奇婆子  阅读(258)  评论(0编辑  收藏  举报