HODJ 1997 汉诺塔VII 简单解题报告
重新拾起放下很久的算法和ACM。自己在杭电上做题也只是练练算法而已,而没有想参加竞赛,纯粹的兴趣~汉诺塔这道题一直解决不了,今天又试着做了一遍,还是没有做出来。借鉴大牛的思想,简单说说,大牛见笑了^_^
要判断给定的状态是否在移动过程中出现,我们可以这样做:
1. 每次必须将当前最大盘从A柱移动到C柱,则当前的最大盘必然不在B柱上。若在B柱上,结束判断,输出false。
2. 最大盘在A柱上,则判定次大盘,目标柱变为B柱。方便处理,将B,C柱交换。
3. 最大盘在C柱上,则判定次大盘,目标柱变为C柱。方便处理,将A,B柱交换。
代码如下:
#include <iostream> using namespace std; int main() { int s; int n; int i,j; int a,b,c; int t[3][64]; int num[3]; int cas; cin>>cas; while(cas--) { cin>>n; a=0;b=1;c=2; for(i=0;i<3;i++) for(j=0;j<n;j++) t[i][j]=0; for(i=0;i<3;i++) { cin>>num[i]; for(j=0;j<num[i];j++) { cin>>s; t[i][s-1]=1; } } while(n--) { if(t[b][n]) { cout<<"false"<<endl; break; } if(t[a][n]) { i=b; b=c; c=i; } else if(t[c][n]) { i=a; a=b; b=i; } } if(n==-1) cout<<"true"<<endl; } }
以前学过的汉诺塔移动方式的算法是:
#include <iostream> using namespace std; void hanno(int n,char a,char b,char c) { if(n) { hanno(n-1,a,c,b); cout<<a<<"->"<<c<<endl; hanno(n-1,b,a,c); } } int main() { int n; cin>>n; hanno(n,'a','b','c'); }
交换方式也是先BC,再移动最大盘后,交换AB,道理是相通的。