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,道理是相通的。

posted @ 2013-01-26 21:08  SF-_-  阅读(566)  评论(0编辑  收藏  举报