1. 汉诺塔问题:
问题描述:有三个柱子A,B,C,现在需要将柱子A上面n个由小到大放置的盘子移到柱子C上,移动规则是:每次只能移动一个盘子,盘子放置只能是大盘子在下面,小盘子在上面。
// n带表盘子的数目,
// fromPeg是n盘子最初所在的柱子
// auxPeg是中间用于借助移动的柱子
// toPeg是最终n盘子需要全部放上去的柱子
void Tower(int n, char fromPeg, char auxPeg, char toPeg)
{
if (n == 1) // 当盘子数目为1,直接移动
{
cout << "Move Disk 1 from Peg " << fromPeg << "to Peg " << toPeg << endl;
return;
}
Tower(n - 1, fromPeg, toPeg, auxPeg); // 先把fromPeg上n-1个柱子,借助toPeg移动到auxPeg
cout << "Move Disk " << n << " from Peg " << fromPeg << "to Peg " << toPeg << endl; // 从fromPeg移动第n个圆盘到toPeg上
Tower(n - 1, auxPeg, fromPeg, toPeg); // 把auxPeg上n-1个柱子,借助fromPeg移动到toPeg
}
2. 逆波兰表达式
逆波兰表达式的定义:每一运算符都置于其运算对象之后,故称为后缀表示。
比如中缀表达式为:(12 + 36) / (1+3) * (15 - 8), 对应的逆波兰表达式为:* / + 12 36 + 1 3 - 15 8
// 逆波兰表达式的计算(递归实现)
// 输入 * / + 12 36 + 1 3 - 15 8
// 输出 48
double Notation()
{
char str[10];
cin >> str;
switch(str[0]) // 获取输入的第一个字符,对应运算符的处理
{
case '+':
return Notation() + Notation();
case '-':
return Notation() - Notation();
case '*':
return Notation() * Notation();
case '/':
return Notation() / Notation();
default:
return atof(str); // 返回最终结果
}
}
3. m个苹果放置在n个盘子的不同方法
要求:不能有重复的,比如:三个盘子放7个苹果,若按照1,1,5和 5,1,1放置,为相同放置方法
int Methods(int m, int n)
{
if (m <= 1 || n <= 1) // 盘子或者苹果数目不超过1个,返回1
return 1;
else if (m < n) // 当苹果的个数小于盘子的个数,等价于Metheds(m,m)
return Methods(m, m);
else
return Methods(m, n-1) + Methods(m - n, n); // 否则,结果为:1个盘子为空,m个苹果放置n-1盘子的情况和至少每个盘子放了一个苹果的情况之和
}