汉诺塔相关,递归(新汉诺塔问题,uva 10795)

来源:互联网 发布:12864与单片机仿真 编辑:程序博客网 时间:2024/06/07 02:34

想到了要有一个中间状态,要递归求解,但最后还是没想通。在汉诺塔问题中,小块是可以无视垫在最底下的大块的。这就为递归奠定了基础。我们只要先把大块处理好,剩下的小块就可以无视大块处理了。我们先处理最大的需要移动的块那么所有比他小的块就需要先移到备用柱上,然后才可以移动最大快。处理完这个最大快后,就可无视掉他,然后递归处理下一个更小的最大块了。而中间状态就是第一个需要移动的最大块可以移动的状态。


注意一个细节

1ll<<(k-1)

代码

#include<bits/stdc++.h>using namespace std;typedef long long ll;ll N;ll S[65];ll E[65];ll kase;ll f(ll P[],ll k,ll to){    if(k==0) return 0;    if(P[k]==to) return f(P,k-1,to);    return f(P,k-1,6-P[k]-to)+(1ll<<(k-1));}int main(){    while(scanf("%lld",&N)==1&&N)    {        for(ll i=1;i<=N;i++)            scanf("%lld",&S[i]);        for(ll i=1;i<=N;i++)            scanf("%lld",&E[i]);        ll k=N;        while(k&&S[k]==E[k]) k--;        printf("Case %lld: %lld\n",++kase,k?f(S,k-1,6-S[k]-E[k])+f(E,k-1,6-S[k]-E[k])+1:0);    }    return 0;}


0 0