• 17.11.17 递归作业


     习题(15-1) 前缀表达式 (1010)

    描述
    前缀表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的前缀表示法为+ 2 3。前缀表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的前缀表示法为* + 2 3 4。本题求解前缀表达式的值,其中运算符包括+ - * /四个。
    
    
    关于输入
    输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。
    
    
    关于输出
    输出为一行,表达式的值。  可直接用printf("%f ", v)输出表达式的值v。
    
    
    例子输入
    * + 11.0 12.0 + 24.0 35.0
    例子输出
    1357.000000
     
    提示
    可使用atof(str)把字符串转换为一个double类型的浮点数。atof定义在stdlib.h中。  此题可使用函数递归调用的方法求解。

     

     1 #include <iostream>
     2 #include<cstring>
     3 using namespace std;
     4 char str[100][20];        //定义一个字符数组,以空格为界,每行存放一个符号或数
     5 int strcount = 0;        //定义符号和数的总数目
     6 double res;       //定义结果
     7 void input()        //此函数用作输入表达式,存入数组
     8 {
     9     int  i = 1, j = 0;
    10     char ch;
    11     while (cin.get(ch))
    12     {
    13         if (ch == ' ')
    14         {
    15             i++;
    16             j = 0;
    17         }
    18         else if (ch == '
    ')
    19             break;
    20         else
    21         {
    22             str[i][j] = ch;
    23             j++;
    24         }
    25     }
    26     strcount = i;
    27 }
    28 int calc(int num)          //此函数用以递归计算
    29 {
    30     double sum,a1,a2;
    31     if (num == 0)
    32     {
    33         res = atof(str[1]);
    34         return 0;
    35     }
    36     if (str[num][0] == '+')
    37     {
    38         a1 = atof(str[num + 1]); a2 = atof(str[num + 2]);
    39         sum = a1 + a2;
    40         sprintf(str[num], "%.10f", sum);
    41         for (int i = 3; i <= strcount - num; i++)
    42             strcpy(str[num + i - 2], str[num + i]);
    43     }
    44     else if (str[num][0]=='*')
    45     {
    46         a1 = atof(str[num + 1]); a2 = atof(str[num + 2]);
    47         sum = a1 * a2;
    48         sprintf(str[num], "%.10f", sum);
    49         for (int i = 3; i <= strcount - num; i++)
    50             strcpy(str[num + i - 2], str[num + i]);
    51     }
    52     else if (str[num][0] == '/')
    53     {
    54         a1 = atof(str[num + 1]); a2 = atof(str[num + 2]);
    55         sum = a1/ a2;
    56         sprintf(str[num], "%.10f", sum);
    57         for (int i = 3; i <= strcount - num; i++)
    58             strcpy(str[num + i - 2], str[num + i]);
    59     }
    60     else if (str[num][0] == '-')
    61     {
    62         a1 = atof(str[num + 1]); a2 = atof(str[num + 2]);
    63         sum = a1 - a2;
    64         sprintf(str[num], "%.10f", sum);
    65         for (int i = 3; i <= strcount - num; i++)
    66             strcpy(str[num + i - 2], str[num + i]);
    67     }
    68     calc(num - 1);
    69 }
    70 int main()
    71 {
    72     input();
    73     calc(strcount);
    74     printf("%f
    ", res);
    75 }
    View Code

     猴子分苹果

    描述
    有1堆苹果共 m 个,由 n 只猴子按个数平均分配。每次到达苹果堆放地的猴子只有1只,而且每个猴子都会平均分 1 次苹果。第1个到达的猴子将苹果平均分成 n 等份,但发现多 k ( k < n )个,于是,将多余的k个扔掉,然后拿走其中的1等份。第 2 个猴子同样将剩余的苹果又分成 n 等份,也发现多 k 个,并同样将多余的 k 个扔掉,然后拿走其中1等份。之后的每个猴子都这样(将剩余的苹果又分成 n 等份,也发现多 k 个,并将多余的 k 个扔掉,然后拿走其中1等份)。假设最后的猴子分配后至少可以拿走1个苹果,请根据输入的 n 和 k值,计算最小的 m
    
    
    关于输入
    输入猴子数目n 和扔掉的个数 k,其中 k 小于 n,n 和 k 之间以空格间隔。
    
    
    关于输出
    输出最小苹果数目
    
    
    例子输入
    2 1
    例子输出
    7

     

     1 #include <iostream>
     2 using namespace std;
     3 int n, k,i=1;           //定义初始值
     4 int monk(int p, int k)       //此函数用以递归求值
     5 {
     6     int num;
     7         if (p == 1)      //当猴子只剩一只的时候,最小值为n*i+k
     8             return n*i + k;
     9         else
    10         {
    11             num = monk(p - 1, k) / (n - 1)*n + k;
    12             if (monk(p - 1, k) % (n - 1) == 0)  //当这种i取值符合时,正常输出
    13                 return num;
    14             else        //不符合时,换一个i,继续尝试
    15             {
    16                 i++;
    17                 return monk(p, k);
    18             }
    19         }
    20 }
    21 int main()
    22 {
    23     cin >> n>>k;
    24     cout << monk(n, k);
    25 return 0;
    26 }
    View Code

     二叉树

    描述
     
    由正整数1, 2, 3, ...组成了一棵无限大的二叉树。从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从10到根结点的路径是(10, 5, 2, 1),从4到根结点的路径是(4, 2, 1),从根结点1到根结点的路径上只包含一个结点1,因此路径就是(1)。对于两个结点x和y,假设他们到根结点的路径分别是(x1, x2, ... ,1)和(y1, y2, ... ,1)(这里显然有x = x1,y = y1),那么必然存在两个正整数i和j,使得从xi 和 yj开始,有xi = yj , xi + 1 = yj + 1, xi + 2 = yj + 2,... 现在的问题就是,给定x和y,要求xi(也就是yj)。
    
    
    关于输入
    输入只有一行,包括两个正整数x和y,这两个正整数都不大于1000。
    
    
    关于输出
    输出只有一个正整数xi
    
    
    例子输入
    10 4
    例子输出
    2
     1 #include <iostream>
     2 #include<cmath>
     3 using namespace std;
     4 int search(int row,int x)        //此函数用以找出x到1路径的下一步将是哪个数,并直接赋给x
     5 {
     6     double mul=row;
     7     return pow(2, mul - 1) + (x - pow(2,mul)) / 2;
     8 }
     9 int check(int x, int y)         //此函数用于判断此时x和y是否相等
    10 {
    11     int sizex, sizey;
    12     for (int i = 1;; i++)    //下面两个循环分别求出x,y处于第几行
    13     {
    14         double mul = i;
    15         if (x <= pow(2, mul)-1)
    16         {
    17             sizex = i - 1;
    18             break;
    19         }
    20     }
    21     for (int i = 1;; i++)
    22     {
    23         double mul = i;
    24         if (y <= pow(2,mul)-1)
    25         {
    26             sizey = i - 1;
    27             break;
    28         }
    29     }
    30     if (y > x)    //如果y比x大,对y进行search,然后递归
    31     {
    32         y = search(sizey, y);
    33         check(x, y);
    34     }
    35     else if (y == x)
    36         return x;
    37     else if(x>y)
    38     {
    39         x = search(sizex, x);
    40         check(x, y);
    41     }
    42 }
    43 int main()
    44 {
    45     int x, y;
    46     cin >> x >> y;
    47     cout << check(x, y) << endl;
    48     return 0;
    49 }
    View Code

    红与黑

    描述
    有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的四块瓷砖中的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
    
    
    关于输入
    包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下  ‘.’:黑色的瓷砖  ‘#’:红色的瓷砖  ‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中仅出现一次  当在一行中读入的是两个零时,表示输入结束。
    
    
    关于输出
    对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
    
    
    例子输入
    6 9
     ....#.
     .....#
     ......
     ......
     ......
     ......
     ......
     #@...#
     .#..#.
     11 9
     .#.........
     .#.#######.
     .#.#.....#.
     .#.#.###.#.
     .#.#..@#.#.
     .#.#####.#.
     .#.......#.
     .#########.
     ...........
     11 6
     ..#..#..#..
     ..#..#..#..
     ..#..#..###
     ..#..#..#@.
     ..#..#..#..
     ..#..#..#..
     7 7
     ..#.#..
     ..#.#..
     ###.###
     ...@...
     ###.###
     ..#.#..
     ..#.#..
     0 0
    例子输出
    45
     59
     6
     13
     1 #include <iostream>
     2 #include<cmath>
     3 using namespace std;
     4 int col,row,bcount=0;         //定义行列数,计数
     5 char ch[21][21];         //定义石砖分布
     6 void hh(int x, int y)           //此函数用于弄清有几块可以走到的石砖
     7 {
     8     if (x<1 || x>row || y<1 || y>col || ch[x][y] != '.')
     9         return;
    10     else
    11     {
    12         ch[x][y] = '#';     //一块黑砖走到以后就把他变成红的防止重复走
    13         bcount++;
    14         hh(x+1,y); hh(x-1,y);
    15         hh(x, y + 1); hh(x, y - 1);
    16     }
    17 }
    18 int main()
    19 {
    20     int startcol, startrow;         
    21     while (1)
    22     {
    23         cin >>col >> row;            //进行输入
    24         if (col == 0)
    25             return 0;
    26         for (int i = 1; i <= row; i++)
    27             for (int j = 1; j <= col; j++)
    28             {
    29                 cin >> ch[i][j];
    30                 if (ch[i][j] == '@')          //遇到@时把他变成.,记下方位
    31                 {
    32                     startcol = j; startrow = i;
    33                     ch[i][j] = '.';
    34                 }
    35             }
    36     hh(startrow, startcol);
    37     cout << bcount << endl;
    38     bcount = 0;
    39     }
    40     
    41     return 0;
    42 }
    View Code

    放苹果问题

    描述
    把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法(用K表示)?注意:5,1,1和1,5,1是同一种分发。
    
    
    关于输入
    第一行是测试数据的数目t(0<= t <= 20),其后的t行均包含两个整数M和N,以空格分开。  1<= M <= 25;  1<= N <= 10;
    
    
    关于输出
    对输入的每组数据M和N,用一行输出相应的K
    
    
    例子输入
    1
     7 3
    例子输出
    8
    提示
    采用递归思想解题。
     1 #include <iostream>
     2 #include<cmath>
     3 using namespace std;
     4 int app(int m, int n)          //此函数用以递归求出方案数
     5 {
     6     if (m == 0 || n == 1)     //最终情况是m=0或者n=1时候的,此时有一种方案符合
     7         return 1;
     8     else
     9     {
    10         if (m >= n)        //当盘子不比苹果多,有放满和不放满两种情况
    11             return app(m, n - 1) + app(m - n, n);
    12         else                //当盘子比苹果多,必须有n-m个盘子是空的,相当于m个苹果放在m个盘子
    13             return app(m, m);
    14     }
    15 }
    16 int main()
    17 {
    18     int co;
    19     cin >> co;
    20     for (int i = 1; i <= co; i++)
    21     {
    22         int m, n;
    23         cin >> m >> n;
    24         cout << app(m, n) << endl;
    25     }
    26     return 0;
    27 }
    View Code

    1090 分解因数

    描述
    给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * ... * an,并且1 < a1 <= a2 <= a3 <= ... <= an,问这样的分解的种数有多少。注意到a = a也是一种分解。
    
    
    关于输入
    第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数a (1 < a < 32768)
    
    
    关于输出
    n行,每行输出对应一个输入。输出应是一个正整数,指明满足要求的分解的种数
    
    
    例子输入
    2
     2
     20
    例子输出
    1
     4
     1 #include <iostream>
     2 #include<cmath>
     3 using namespace std;
     4 int sum = 1;           //定义一个全局变量,是输出结果
     5 void res(int m,int a)           //此函数用于算出,当最小的因数大于等于a时,m的分法有几种
     6 {
     7     for (int i =a; i <= sqrt(m); i++)    //循环出不同情况,并且因为因数从小到大,i有最大界限
     8     {
     9         if (m%i == 0)   //当i是因数的时候,多一种分法,并递归余数
    10         {
    11             sum++;
    12             res(m / i,i);
    13         }
    14     }
    15 }
    16 int main()
    17 {
    18     int n,a;
    19     cin >> n;
    20     for(int i=1;i<=n;i++)
    21     {
    22         cin >> a;
    23         res(a,2);        //初始时,最小因数大于等于2
    24         cout << sum << endl;
    25         sum = 1;
    26     }
    27 }
    View Code
    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    985大学的部分课程链接
    SVD学习
    资源三:机器学习源代码
    资源二:计算机视觉,机器学习方面牛人网站链接
    资源一:计算机视觉,机器学习方面的论文和算法代码
    PHPCMS v9 分析(1)
    highcharts 配置选项
    highcharts 基本组成
    Jquery 代码性能改善
    非80端口的网站发布后外网访问的问题
  • 原文地址:https://www.cnblogs.com/yalphait/p/7899014.html
Copyright © 2020-2023  润新知