题目
Problem Description
不知道大家有没有玩过一个叫做 九连环 的玩具,如下图所示。
如果你不了解九连环,那玄黄就带你领略九连环的奥妙:
九连环是我国传统的民间智力玩具,玩具上面有九个连环套在杆上,目标就是通过一定的方式将九个连环从杆上全部取下来。
玩法是这样的:
1、对每个环,有2种操作:把这个环放到杆上或把这个环从杆上取下
2、你可以随意的对第1个环进行操作
3、如果你想对第i个环(i>1)进行操作,你必须将第i-1个环放在杆上,且必须把前i-2个环从杆上取下
Input
输入一个整数n ( 0<n<10 ),代表杆上面的连环个数。
Output
输出把所有连环取下来的最少操作步骤,每一步占一行,输出一个整数i和操作”UP”或者”DOWN”,代表将第i个环放到杆上或从杆上取下来,整数和操作用空格分开。详情见示例输出。
Sample Input
4
Sample Output
2 DOWN 1 DOWN 4 DOWN 1 UP 2 UP 1 DOWN 3 DOWN 1 UP 2 DOWN 1 DOWN
思路
一看就知道是一个简单的递归,可能是个人比较菜的原因,感觉实现起来略微有点复杂= =
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
int a[20]; //记录当前环的状态,0表示未取下
void f(int x,int y) // 第x个环要进行y操作,y==0表示要将其取下
{
if(x == 0) { //第0个环不存在
return ;
}
if(x == 1) { //第1个环可以任意操作
if(y==1 && a[x]==1) {
printf("1 UP\n");
a[x] = 0;
}
else if(y==0 && a[x]==0) {
printf("1 DOWN\n");
a[x] = 1;
}
return ;
}
// 剩下的位置上的环
if(a[x-1]) { //操作第x个环前,第x-1个要未取下
f(x-1,1);
}
for(int i=x-2; i>0; i--) { //前x-2个要已取下
if(!a[i]) {
f(i,0);
}
}
if(y==1 && a[x]==1) {
printf("%d UP\n",x);
a[x] = 0;
}
else if(y==0 && a[x]==0) {
printf("%d DOWN\n",x);
a[x] = 1;
}
}
int main()
{
memset(a,0,sizeof(a));
a[0] = 1;
int n;
scanf("%d",&n);
for(int i=n; i>0; i--) { //从大往小依次取下,因为操作一个环的条件只于其前面的环有关
if(!a[i]) {
f(i,0);
}
}
return 0;
}