Hanoi Series topics (progressive understanding of recursive recursion)

Source: Internet
Author: User

The most bare Hanoi:

Step one: Move the n-1 plate to the B-pillar.

Step two: Move the nth pillar to column C

Step three: Move the n-1 plate to the C drive.

The first and third steps are the same, if you only need the minimum number of steps, you can use recursion to write it out regardless of the intermediate step.

Core code

A[1]=1;

for (int i=2;i<=n;i++)

a[i]=2*a[i-1]+1;


The most naked figure of course is not enough, now let's look at some variants

hdu2175

Enter N,m, ask for the initial n plates, ask the plate number of moving the first m

I look very troublesome, in fact, it is very simple.

For example, there are 4 plates, I want to see the 4th step of the plate. If I moved 3 plates to the destination column, that would take 7 steps, if the 2 plates were moved to the destination column, that would take 3 steps, so the 4th move must be on the top 3 plates.

And we can use this idea to keep pushing/recursion, until exactly equal to moving some plates to the destination column.

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
ll n,m,a[64],b[64];
void Inial ()
{
    a[1]=1;b[0]=1;b[1]=2;
    for (int i=2;i<64;i++)
    {
        a[i]=a[i-1]*2+1;
        if (i<63)
            b[i]=a[i]+1;
    }
}
int Sovle ()
{
    if (m==a[63])
        return 1;
    while (m>0)
    {
        int t=0;
        while (t<63)
        {
            if (m>b[t])
                t++;
            else break
                ;
        }
        if (M==b[t])
            return t+1;
        M-=B[T-1];
    }
}
int main ()
{
    inial ();
    while (cin>>n>>m&&n&&m)
    {
        cout<<sovle () <<endl;
    }
    return 0;
}


hdu2511

The following topics are more advanced than the previous one.

Input n,m ask n a plate, which plate is moved by step m, and which plate the output is moved from (one step above the previous one)

Let's think about it. If M step is exactly K-plate moved to the destination column, then this time must be the 1th plate from the column, moving K disk in the destination column. The pillar of 1 is the column in our recursive function, then the destination column. Let's think about the bare three that I started talking about, moving n disks to move the n-1 to B, that for n-1, the Middle B is the goal column, C is the middle column, then for the n-2, the purpose column is the C column, the middle Pillar B column, Then judge the purpose column of K-disk is which directly judge the difference between his and n parity can be.

#include <iostream> #include <stdio.h> #include <math.h> #include <algorithm> using namespace
Std
typedef long Long LL;
ll A[64],m;
int t,n;
    void Inal () {a[1]=1;
for (int i=2;i<=63;i++) a[i]=2*a[i-1]+1; } void Sovle (int s,int t,int z,int N) {//cout<< "-----------" <<s<< "<<t<<" "<<z<
    < "" <<n<<endl;
    int k=1;
    while (k<64&&m-a[k]>0) k++;
    k--;
    M-=A[K];
    int d= (N-K) &1; if (d==1)//1 to K on z {if (m==0) {cout<<1<< "" <<s<< "" &LT;&LT;Z&LT;&L
            T;endl;
        Return
            } if (m==1) {cout<<k+1<< "" <<s<< "" <<t<<endl;
        Return
        } m--;
    Sovle (Z,T,S,K); } ELSE//1 to K on t {if (m==0) {cout<<1<< "" <<s<< "" <<t<
            <endl;
Return        } if (m==1) {cout<<k+1<< "" <<s<< "" <<z<<endl;
        Return
        } m--;
    Sovle (T,Z,S,K);
    }} int main () {inal ();
    scanf ("%d", &t);
        while (t--) {scanf ("%d%i64d", &n,&m);
    Sovle (1,3,2,n);
} return 0; }


hdu2184

Let's go further, step m, output the number of the plates on the three pillars.

If you look directly at this question will be frightened, but there is the accumulation of the previous topic, the problem is only a step forward. Eg:4 a plate, 5th step, 3 plates to the destination column, it takes 7 steps, 2 plates move to the destination column takes 3 steps,

It can be decided here that the 4th plate must not move on the original pillar, and the 3rd plate will move to the middle column. Isn't it convenient to write a recursive function? How to save the plate number on each pillar? Due to the nature of recursion, large plates are determined first, and the smaller plates on the pillars may be determined in the next level of recursion. Output is the first output of large output small, first-out, not the queue.

#include <iostream> #include <stdio.h> #include <math.h> #include <algorithm> #include <
Cstring> #include <queue> using namespace std;
typedef long Long LL;
ll A[64],m;
int t,n,len[4];
Queue<int> Qu[4];
    void Inal () {a[1]=1;
for (int i=2;i<=63;i++) a[i]=2*a[i-1]+1;
    } void Sovle (int s,int t,int z,int n) {int k=1;
    while (k<64&&m-a[k]>0) k++;
    k--;
        for (int i=n;i>k+1;i--) {len[s]++;
    Qu[s].push (i);
    } M-=a[k];
    int d= (N-K) &1;
    if (d==0) swap (z,t);
            if (m==0) {for (int i=k;i>=1;i--) {len[z]++;
        Qu[z].push (i);
        } len[s]++;
        Qu[s].push (k+1);
    Return
    } len[t]++;
    Qu[t].push (k+1);
            if (m==1) {for (int i=k;i>=1;i--) {len[z]++;
        Qu[z].push (i);
    } return;
    } m--;
Sovle (Z,T,S,K); } int main () {INAL ();
    scanf ("%d", &t);
        while (t--) {memset (len,0,sizeof (len));
        scanf ("%d%i64d", &n,&m);
        Sovle (1,3,2,n);
            for (int i=1;i<=3;i++) {printf ("%d", len[i]);
            printf ("%d", Qu[i].front ());
            Qu[i].pop ();
                while (!qu[i].empty ()) {printf ("%d", Qu[i].front ());
            Qu[i].pop ();
        } printf ("\ n");
}} return 0; }

hdu1995

The question is to move n plates to the destination column and ask how many times the K plate has been moved in the process.

Look very complicated, but think about it, the nth plate only need 1 times, the first n-1 plate only need to move 2 times, you can recursively go down, of course, have the feeling can also directly find the law, do not say, on the code

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long Long ll;
int T,n,K;
int main ()
{
    scanf("%d",&t);
    while (T--)
    {
        scanf("%d%d",&n,&k);
        ll ans=pow(2,n-k);
        printf("%i64d\n",ans);
    }
    return 0;
}

hdu1996

Ask n a plate, moving to the goal column process (regardless of the optimal situation) will produce the total number of series, low question, each OH case can be on three pillars, 3 of the class will do

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
ll a[31];
void Inial ()
{
    a[0]=1;
    for (int i=1;i<=30;i++)
        a[i]=3*a[i-1];
}
int main ()
{
    inial ();
    int t,k;
    scanf ("%d", &t);
    while (t--)
    {
        scanf ("%d", &k);
        printf ("%i64d\n", A[k]);
    }
    return 0;
}


Two of the above is a break, now look at more in-depth, more interesting Hanoi, hdu1997, I see test instructions AH

This question is not a see on the people scare, for this problem, must be recursive. The question now is what to recursion, and if you're going to pass each step, it's definitely going to explode. We have to figure out what we can determine, because of the bare formula, we can be sure that n is in a or C, and if n is OK, then we need to consider n-1. If n is in a, that is also the first step in the bare formula, then the n-1 is only in a or B, the destination bar is B, the starting point is a, the middle point is c. If n to C, that must have gone through the first step, then n-1 either in C or B, the starting point is B, the middle point is a, the destination is C.

#include <iostream> #include <stdio.h> #include <algorithm> using namespace std;
const int m=70;
int t,n,len[4],a[4][m],no[4],f=-1;
    void input () {scanf ("%d", &n);
        for (int i=0;i<3;i++) {scanf ("%d", &len[i]);
    for (int j=0;j<len[i];j++) scanf ("%d", &a[i][j]);
    }} void Dfs (int a,int b,int c,int N) {if (f!=-1) return;
        if (n==0) {f=1;
    Return
        } if (a[a][no[a]]==n) {no[a]++;//cout<<n<< "-------" <<A<<endl;
    DFS (A,C,B,N-1);
        } else if (a[c][no[c]]==n) {no[c]++;//cout<<n<< "-------" <<C<<endl;
    DFS (B,A,C,N-1);
        } else {f=0;
    Return
    }} int main () {scanf ("%d", &t);
        while (t--) {input ();
        no[0]=no[1]=no[2]=0;
        F=-1;
        DFS (0,1,2,n);//cout<<f<<endl;
   if (f) puts ("true");     Else puts ("false");
} return 0; }

We do some Hanoi that change the rules.

hdu2064 plates cannot be directly from a to C, only from B to C first.

Learn to recursive formula, can not find the words, the first to simulate a few plates

N-1 a plate first move to c,n move to b,n-1 plate move to a,n move to c,n-1 plate move to C

#include <iostream>
#include <stdio.h>
using namespace std;
typedef long long LL;
ll f[37];
void Inial ()
{
    f[1]=2;
    for (int i=2;i<36;i++)
        f[i]=3*f[i-1]+2;
}
int main ()
{
    inial ();
    int n;
    while (scanf ("%d", &n)!=eof)
    {
        cout<<f[n]<<endl;
    }
    return 0;
}

hdu2077

The rule is changed on the basis of hdu2064, the largest plate can be placed on the top of the small plate (top)

In combination with the above question, n-1 the rules of the title move to B,n to B, then to C, then n-1 to C

#include <iostream>
#include <stdio.h>
using namespace std;
typedef long long LL;
ll a[37],b[37];
void Inial ()
{
    a[1]=2;
    B[1]=1;
    for (int i=2;i<=20;i++)
    {
        a[i]=3*a[i-1]+2;
    }
    for (int i=2;i<=20;i++)
    {
        b[i]=b[i-1]+a[i-1]+1;
    }
}
int main ()
{
    inial ();
    int n,m;cin>>n;
    for (int i=0;i<n;i++)
    {
        cin>>m;
        cout<<b[m-1]*2+2<<endl;
    }
    return 0;
}

hdu1207

The rule has made a change again, this time has four pillars, this problem is the inertial thinking (inertia thinking killed people ah ...) ), we all use recursion to do, in fact, is inside the soft DP. We feel the deep malice from the world.

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
Double a[65],b[65];
void Inial ()
{
   b[1]=1;
   for (int i=2;i<65;i++)
    b[i]=2*b[i-1]+1;
   A[1]=1;
   a[2]=3;
   for (int i=3;i<=64;i++)
   {
       a[i]=b[i];
       for (int j=1;j<i;j++)
       {
           a[i]=min (2*a[j]+b[i-j],a[i]);
}}} int main ()
{
    int n;
    Inial ();
    while (scanf ("%d", &n)!=eof)
    {
        cout<<a[n]<<endl;
    }
    return 0;
}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.