任务描述
本关任务:将一个整数进行进制转换。
相关知识
汉诺塔问题
这是一个经典的递归问题:
有一根杆子上从下往上串着n个依次增大的盘子,请利用第二根杆子,将这些盘子移动到第三根杆子上。
要求一次只能移动一个盘子,且大盘子不能放到小盘子上。
对于这个问题,我们可以采用递归的方式来思考:
先将上面n-1个碟子移动到第二个柱子上。
然后将第n个碟子移动到第三个柱子上。
最后将第二个柱子上的n-1个碟子移动到第三个柱子上。
如果我们用一个函数move(n,from,tmp,to)来表示移动盘子的动作,其中:
n为要移动的碟子数。
from为移动的碟子所在的柱子。
tmp为移动过程中能借助的柱子。
to为碟子要移动到的目的柱子。
则上面的过程可以表示为:
move(n - 1,from,to,tmp);
move(1,from,tmp,to);
move(n - 1,tmp,from,to);
如果只有一个盘子要移动,那就直接将其移动到目的柱子上,即:
if(n == 1)
printf("%c->%c\n",from,to);
将这两段代码组合起来,就是:
void move(int n,char from,char tmp,char to)
{
if(n == 1)
printf("%c->%c\n",from,to);
else
{
move(n - 1,from,to,tmp);
move(1,from,tmp,to);
move(n - 1,tmp,from,to);
}
}
如果用3、A、B、C来调用它,即move(3,'A','B','C'),得到的结果是:
A->C
A->B
C->B
A->C
B->A
B->C
A->C
可以根据输出的步骤模拟移动一下,看看是否正确!
总的来说,使用递归模拟连续发生的动作,有以下步骤:
确定连续发生的动作。
确定连续次动作之间的关系。
确定边界条件。
编程要求
之前我们学习过使用迭代方式来进行进制转换的方法,这次希望你能用递归来解决这个问题。
右侧编辑器中有一个函数Conv,它有两个参数n和k,n为非负数,1 < k <= 10。
请在此函数,将n按照k进制输出,占一行。
输入数据由评测系统读取,并传递给Conv函数。具体见测试说明。
测试说明
平台会对你编写的代码进行测试:
预期输入:10 9
预期输出:11
预期输入:12 4
预期输出:30
每组输入有一行,包含两个整数,分别是n和k。
参考代码:
#include <iostream>
using namespace std;
// 辅助函数,用于执行递归转换
void convert(int n, int k) {
if (n == 0) {
return; // 基本情况:没有东西要打印
}
convert(n / k, k); // 递归调用,使用商作为参数
cout << n % k; // 打印余数(基数k下的当前数字)
}
void Conv(int n, int k) {
if (n == 0) {
cout << 0; // 处理n为0的情况
} else {
convert(n, k); // 调用递归转换函数
}
cout << endl; // 在输出后打印一个新行
}