212
社区成员
L2-1【用递归实现】 九连环问题
分数 10
作者 李祥
单位 湖北经济学院
题目
九连环是一种流传于山西省的传统民间的智力玩具,由九个圆环相连成串,以解开为胜。
九连环的九个环,一环扣一环地套在钗上。除了第 1 号环可以随时装上或卸下以外,其它环装上或卸下的条件是:在它的前面仅有紧靠它那一个环在钗上。即:当第 1 ~ i−2 号环都不在钗上,第 i−1 号环在钗上,这时可以装上或卸下第 i 号环。
输入格式
环数 操作(U表示装上, D表示卸下)
输出格式
装上或卸下九连环的操作步骤
每行显示一步操作,具体格式为:
环号: U或D (U表示装上,D表示卸下)
输入样例1
3 U
输出样例1
1: U
2: U
1: D
3: U
1: U
输入样例2
4 D
输出样例2
2: D
1: D
4: D
1: U
2: U
1: D
3: D
1: U
2: D
1: D
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
思路
1、装环:当装上第n环时,首先需装上第n-1环,装上第n-1环之前,需装上第n-2环,依次往前推,则应先装上第1环,再装上第2环;再卸下第1环剩余第2环,可以装上第3环,卸下第2环剩余第3环,可以装上第4环,依次往后推,卸下第n-2环后,可以装上第n环;再按照之前的步骤,依次将环全部装上。
2、卸环:当卸下第n环时,首先需卸下第n-2环,要卸下第n-2环,需卸下第n-4环,依次往前推,则应先卸下第1环,再卸下第3环,装上第一环,卸下第2环,卸下第一环,再卸下第五环;装上第一环,装上第二环,卸下第一环,装上第三环,装上第一环,卸下第二环,卸下第一环,卸下第四环……后面每卸下一环,都需按照此步骤装上再卸下,直到卸下第n环,再依次将后面的环全部卸下。
3、无论结果如何,最后一步一定是第一环的装上与卸下,即最终结果一定返回到1。
代码如下:
#include <stdio.h>
void D(int n);
void U(int n);
int main() {
int n;
char a;
scanf("%d %c",&n,&a);
if(a=='U'){
U(n);
}else if(a=='D'){ //进行哪种操作,则对应那一函数部分
D(n);
}
return 0;
}
void D(int n) { //定义卸下过程的函数
if(n==1){
printf("1: D\n");
//无论一个环还是多个环,最后一步均是对第1环的操作,直接输出
}else if(n<=0){
return; //n<=0时,则输出n的值及对应操作
}else{
//首先排除1和小于等于0的情况
D(n-2); //卸下第n-2个才能卸下第n个
printf("%d: D\n",n);
//n的值不断在函数D(n)中操作再返回,若大于1,则继续递归,直到环能够被卸下为止
U(n-2);
D(n-1); //装上第n-2个,可以卸下第n-1个,重复该过程,直到全部卸下
}
}
void U(int n) {
if(n==1){
printf("1: U\n");
}else if(n<=0){
return;
}else{
U(n-1);
D(n-2); //装上第n-1个,卸下第n-2个才能装上第n个,n不断递归,直到为1或小于等于0
printf("%d: U\n",n);
U(n-2); //重复装环的过程,直到装上最后一个
}
}
代码运行结果:
问题总结:
弄清楚装环与卸环时函数的递归关系。