汉诺塔
作者:
无双飞怪
,
2024-05-02 21:01:06
,
所有人可见
,
阅读 28
古老的汉诺塔问题是:用最少的步数将N个半径互不相等的圆盘从1号柱利用2号柱全部移动到3号柱,在移动过程中小盘永远在大盘上边。 现在再加上一个条件:不允许从1号柱直接把盘移动到3号柱, 也不允许从3号柱直接移动到1号柱。把盘按半径从小到大1——N进行编号。每种状态用N个整数表示, 第i个整数表示第i号盘所在的柱的编号。则N=2时的移动方案为(1,1)》(2,1)》(3,1)》(3,2)》(2,2)》(1,2)》(1,3)》(2,3) 》(3,3)初始状态为0步,变成求在某步数时的状态。
输入描述
输入文件的第一行为整数T(1<=T<=100),表示输入数据的组数。接下来的T行,每行有两个整数N,M(1<=N<=19, 0<=M<=移动N个圆盘需要的次数)
输出描述
输入文件一共T行对于每组输入数据,输出N个整数表示移动N个盘在M步时的状态,每两个数之间用一个空格隔开,行首和行末不要有多余的空格。
样例输入
3
2 0
2 1
2 2
样例输出
1 1
2 1
3 1
每次都只算变化的部分
因为每六步就会更新两个棋子的状态 所以要除以三
#include<bits/stdc++.h>
using namespace std;
const int N=20;
int a[7]={0,1,2,3,3,2,1};
int ans[N];
int main()
{
int T;
cin>>T;
while(T--)
{
int n,m;
cin>>n>>m;
int k=0;
while(m!=0)
{
k++;
ans[k]=a[m%6+1];
m/=3;
}
for(int i=1;i<=n;i++)
{
if(ans[i]==0) cout<<1;
else cout<<ans[i];
if(i!=n) cout<<' ';
}
cout<<endl;
memset(ans,0,sizeof ans);
}
return 0;
}