新汉诺塔
emmm,今天我们考递归,总体来讲还好,但是最后一道奇怪的汉诺塔根本没看,没想到固输得分了!!!哈哈哈!!!
题目:
新汉诺塔(nhanoi) 题目描述 设有 n 个大小不等的中空圆盘,按从小到大的顺序从 1 到 n 编号。将 这 n 个圆盘任意的迭套在三根立柱上,立柱的编号分别为 A、B、C, 这个状态称为初始状态。 现在要求找到一种步数最少的移动方案,使得从初始状态转变为目 标状态。 移动时有如下要求: ·一次只能移一个盘; ·不允许把大盘移到小盘上面。 输入 第一行是状态中圆盘总数; 第二到第四行分别是初始状态中 A、B、C 柱上圆盘的个数和从上到下 每个圆盘的编号; 第五到第七行分别是目标状态中 A、B、C 柱上圆盘的个数和从上到下 每个圆盘的编号。 输出 每行一步移动方案,格式为:move I from P to Q 最后一行输出最少的步数。 样例输入 5 3 3 2 1 2 5 4 0 1 2 3 5 4 3 1 1 样例输出 move 1 from A to B move 2 from A to C move 1 from B to C move 3 from A to B move 1 from C to B move 2 from C to A move 1 from B to C 7
其实就是一道递归,主要思路是把大的先归位,为了达到这一目的,可以通过把比它小的全移到无关的柱子上去。
代码:
#include <iostream> #include <cstring> using namespace std; int step; char s[4]={' ','A','B','C'}; int xian[64],yuan[64],n; void mov(int c,int b) //c盘子想挪到b { int x,l; if (b==yuan[c]) return; x=6-b-yuan[c]; //x为剩下的那个柱子 for (l=c-1;l>=1;l--) mov(l,x); //把比c盘子小的小盘子挪到x柱上 cout<<"move "<<c<<" from "<<s[yuan[c]]<<" to "<<s[b]<<endl; yuan[c]=b; step++; } int main() { cin>>n; int k,l; for (int i=1;i<=3;i++) { cin>>k; for (int j=1;j<=k;j++) { cin>>l; yuan[l]=i; //n个盘子原来在哪 } } for (int i=1;i<=3;i++) { cin>>k; for (int j=1;j<=k;j++) { cin>>l; xian[l]=i; //n个盘子将要去哪 } } for (int i=n;i>=1;i--) //倒着移动,因为大盘子不影响小盘子 mov(i,xian[i]); cout<<step<<endl; return 0; }
只想找一个不会伤害我的人