递归的几个简单题目
1、
如上图所示,由正整数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)。
10 4
2
#include <iostream> using namespace std; int common(int x, int y) { if(x == y) { return x; } else if(x > y) { return common(x / 2 , y); } else { return common(x , y / 2); } } int main() { int x, y; cin >> x >> y; cout << common(x, y) << endl; }
2、
可直接用printf("%f\n", v)输出表达式的值v。
* + 11.0 12.0 + 24.0 35.0
1357.000000
此题可使用函数递归调用的方法求解。
#include <cstdio> #include <iostream> #include<cmath> #include <string> #include <cstdlib> using namespace std; double fun(void) { string str; cin >> str; switch(str[0]) { case '+' : return fun( ) + fun( );break; case '-' : return fun( ) - fun( );break; case '*' : return fun( ) * fun( );break; case '/' : return fun( ) / fun( );break; default : return atof(str.c_str()); } } int main(void) { freopen("in.txt", "r", stdin); double ans; ans = fun(); printf("%f\n", ans); return 0; }
3、
放苹果
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 22804 | Accepted: 14503 |
Description
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
Input
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
Output
对输入的每组数据M和N,用一行输出相应的K。
Sample Input
1 7 3
Sample Output
8
#include <iostream> using namespace std; int count(int x, int y) { if(y == 1 || x == 0) { return 1; } if(x < y) { return count(x, x); } return count(x, y - 1) + count(x - y, y); } int main() { int t,m ,n; cin >> t; while(t--) { cin >> m >> n; cout << count(m, n) << endl; } return 0; }
4、
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。
6 9 ....#. .....# ...... ...... ...... ...... ...... #@...# .#..#. 0 0
45
#include <iostream> #include <cstring> using namespace std; #define MAX 25 char maps[MAX][MAX]; const int moves[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; bool visited[MAX][MAX]; int n, m; int count; void DFS(int x, int y) { visited[x][y] = true; for(int i = 0; i < 4; i++) { int p = x + moves[i][0]; int q = y + moves[i][1]; if(p >=1 && p <= m && q >=1 && q <= n && !visited[p][q] && maps[p][q] == '.') { count++; visited[p][q] = true; DFS(p , q); } } } int main() { freopen("in.txt", "r", stdin); int i, j, x, y; while(cin >> n >> m) { if(n == 0 && m == 0) break; for(i = 1; i <= m; i++) { for(j = 1; j <= n; j++) { cin >> maps[i][j]; if(maps[i][j] == '@') { x = i; y = j; } } } count = 1; memset(visited, false, sizeof(visited)); DFS(x, y); cout << count << endl; } return 0; }
#include <stdio.h> int W, H; char z[21][21]; int f(int x, int y) { if(x < 0 || x >= W || y < 0 || y >= H) // 如果走出矩阵范围 return 0; if(z[x][y] == '#') return 0; else { z[x][y] = '#'; // 将走过的瓷砖做标记 return 1 + f(x - 1, y) + f(x + 1, y) + f(x, y - 1) + f(x, y + 1); } } int main(void) { int i, j, num; while(scanf("%d %d", &H, &W) && W != 0 && H != 0) { num = 0; for(i = 0; i < W; i++) // 读入矩阵 scanf("%s", z[i]); for(i = 0; i < W; i++) for(j = 0; j < H; j++) if(z[i][j] == '@') printf("%d\n", f (i , j)); } return 0; }
Keep it simple!