洛谷 1242

来源:互联网 发布:怼的网络意思 编辑:程序博客网 时间:2024/05/21 06:43

    汉诺塔,经典的递归问题,我们考虑每个盘子的初态和末态,对于一个盘子的移动限制就是大的不能放在小的上,那么我们肯定是先选择移动大的,那么如何移动?假设我们将一个大的从A移动到C,那么我们一定是把A上的小的和C上的小的移动到B,否则无法移动,这样我们就找到了一种移动方法,从大到小移动,这样移动一定是最少的,因为每一步的移动都是必要的,缺失一步移动大盘子都无法移动。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define maxn 1005int n,a[maxn],b[maxn],tot;char s[5]; void solve(int x,int fr,int to){if (fr==to) return;int res=6-fr-to;for (int i=x-1;i>=1;i--) if (a[i]!=res) solve(i,a[i],res);a[x]=to;tot++;printf("move %d from %c to %c\n",x,s[fr],s[to]);}int main(){scanf("%d",&n);s[1]='A';s[2]='B';s[3]='C';for (int i=1;i<=3;i++) {int k,w;scanf("%d",&k);for (int j=1;j<=k;j++) {scanf("%d",&w);a[w]=i;}}for (int i=1;i<=3;i++) {int k,w;scanf("%d",&k);for (int j=1;j<=k;j++) {scanf("%d",&w);b[w]=i;}}for (int i=n;i>=1;i--) solve(i,a[i],b[i]);printf("%d\n",tot);return 0;}


0 0
原创粉丝点击