习题(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 }
猴子分苹果
描述 | |
有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 }
二叉树
描述 | |
由正整数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 }
红与黑
描述 | |
有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的四块瓷砖中的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。 | |
关于输入 | |
包括多个数据集合。每个数据集合的第一行是两个整数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 }
放苹果问题
描述 | |
把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 }
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 }
时间: 2024-10-06 07:21:08