17.11.17 递归作业

Posted TobicYAL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17.11.17 递归作业相关的知识,希望对你有一定的参考价值。

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

描述
前缀表达式是一种把运算符前置的算术表达式,例如普通的表达式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
 
提示
可使用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 == \n)
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\n", 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
 .#.........
 .#.#######.
 .#.#.....#.
 .#.#.###.#.
 .#.#[email protected]#.#.
 .#.#####.#.
 .#.......#.
 .#########.
 ...........
 11 6
 ..#..#..#..
 ..#..#..#..
 ..#..#..###
 ..#..#..#@.
 ..#..#..#..
 ..#..#..#..
 7 7
 ..#.#..
 ..#.#..
 ###.###
 [email protected]
 ###.###
 ..#.#..
 ..#.#..
 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

 

以上是关于17.11.17 递归作业的主要内容,如果未能解决你的问题,请参考以下文章

数据结构作业代码留存

数据结构作业代码留存

数据结构作业代码留存

动态SQL基础概念复习(Javaweb作业5)

HTML5期末大作业:餐饮美食网站设计——咖啡(10页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 咖啡网页设计 美食餐饮网页设计...(代码片段

递归思想作业