题目描述
设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。
现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态。
移动时有如下要求:
·一次只能移一个盘;
·不允许把大盘移到小盘上面。
输入输出格式
输入格式:文件第一行是状态中圆盘总数;
第二到第四行分别是初始状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号;
第五到第七行分别是目标状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号。
输出格式:每行一步移动方案,格式为:move I from P to Q
最后一行输出最少的步数。
输入输出样例
输入样例#1:
53 3 2 12 5 401 23 5 4 31 1
输出样例#1:
move 1 from A to Bmove 2 from A to Cmove 1 from B to Cmove 3 from A to Bmove 1 from C to Bmove 2 from C to Amove 1 from B to C7
说明
圆盘总数≤45
每行的圆盘描述是从下到上的圆盘编号
Solution:
最近太蠢了,打了个爆搜,爆$0$`~`。。。
正解思路实在是巧妙,我们处理出每个盘的起始位置和目标位置,然后贪心的想到,我们应该从大到小让盘依次移到目标位置,移动过程中就是让小盘让路(即移到另一个中间盘上),然后每次就层层递归,输出就好了。(怎么会有这么巧的思路~)
代码:
#include#define il inline#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)using namespace std;const int N=55;int n,fr[N],to[N],ans;string s="ABC";il void dfs(int u,int v){ if(fr[u]==v)return; Bor(i,1,u-1) dfs(i,6-fr[u]-v); printf("move %d from %c to %c\n",u,s[fr[u]-1],s[v-1]); fr[u]=v,ans++;}int main(){ cin>>n; int t,x; For(i,1,3){ cin>>t; while(t--)cin>>x,fr[x]=i; } For(i,1,3){ cin>>t; while(t--)cin>>x,to[x]=i; } Bor(i,1,n) dfs(i,to[i]); cout<