zoukankan      html  css  js  c++  java
  • 杭电_ACM_汉诺塔VII

    Problem Description
    n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列。由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 : 
    n=m+p+q
    a1>a2>...>am
    b1>b2>...>bp
    c1>c2>...>cq
    ai是A柱上的盘的盘号系列,bi是B柱上的盘的盘号系列, ci是C柱上的盘的盘号系列,最初目标是将A柱上的n个盘子移到C盘. 给出1个系列,判断它是否是在正确的移动中产生的系列.
    例1:n=3
    3
    2
    1
    是正确的
    例2:n=3
    3
    1
    2
    是不正确的。
    注:对于例2如果目标是将A柱上的n个盘子移到B盘. 则是正确的.
     
    Input
    包含多组数据,首先输入T,表示有T组数据.每组数据4行,第1行N是盘子的数目N<=64.
    后3行如下
    m a1 a2 ...am
    p b1 b2 ...bp
    q c1 c2 ...cq
    N=m+p+q,0<=m<=N,0<=p<=N,0<=q<=N,
     
    Output

                对于每组数据,判断它是否是在正确的移动中产生的系列.正确输出true,否则false
     
    Sample Input
    6
    3
    1 3
    1 2
    1 1
    3
    1 3
    1 1
    1 2
    6
    3 6 5 4
    1 1
    2 3 2
    6
    3 6 5 4
    2 3 2
    1 1
    3
    1 3
    1 2
    1 1
    20
    2 20 17
    2 19 18
    16 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
     
    Sample Output
    true
    false
    false
    false
    true
    true
    View Code
     1 #include <stdio.h>
     2 #define MAX 66
     3 //using recursion to judge
     4 int hanoi(int n, int *res, int *des, int *mid)
     5 {
     6     if (*mid == n)
     7     {
     8         return 0;
     9     }
    10     else if (*res == n)
    11     {
    12         return hanoi(n - 1, res + 1, mid, des);
    13     }
    14     else if (*des == n)
    15     {
    16         return hanoi(n - 1, mid, des + 1, res);
    17     }
    18     return 1;
    19 }
    20 int main()
    21 {
    22     int N, n, i, k;
    23     int m, p, q, a[MAX], b[MAX], c[MAX];
    24     //input
    25     scanf("%d", &N);
    26     for (i = 0; i < N; i++)
    27     {
    28         scanf("%d", &n);
    29         scanf("%d", &m);
    30         for (k = 0; k < m; k++)
    31         {
    32             scanf("%d", &a[k]);
    33         }
    34         scanf("%d", &p);
    35         for (k = 0; k < p; k++)
    36         {
    37             scanf("%d", &b[k]);
    38         }
    39         scanf("%d", &q);
    40         for (k = 0; k < q; k++)
    41         {
    42             scanf("%d", &c[k]);
    43         }
    44         //according to input to get the result
    45         if (hanoi(n, a, c, b))
    46             printf("true\n");
    47         else
    48             printf("false\n");
    49     }
    50     return 0;
    51 }

    Algrithm-recursion

    firstly, for A, B, C, you want A->C, so, you will know the biggest one must be on the A or C, if biggest is on B, it will be wrong.

    secondly, if the biggest one is on A, then the second biggest one must be moved from A->B.

    thirdly, if the biggest one is on C, then the second biggest one have been on B. So, you must be moved from B->C.

    according above, you can use recursion easily.

    --------------------------------------------------------

    Key points

    firstly, the recursion is more useful for hanoi, for either recursion, you must to march, and the condition to jump out.

    secondly, for either question, you must analyse in advance, then catch the core, don't waste the energy on other useless things.

  • 相关阅读:
    【刷题】BZOJ 4078 [Wf2014]Metal Processing Plant
    【刷题】BZOJ 4000 [TJOI2015]棋盘
    【刷题】BZOJ 3495 PA2010 Riddle
    【刷题】BZOJ 4977 [Lydsy1708月赛]跳伞求生
    Linux 文件系统 相关
    Ubuntu、Sql Server卸载心得
    CVTE面试总结
    open_clientfd(char* hostname,int port)和open_listenfd(int port)
    将十六进制显示为点分十进制
    Linux 小记录
  • 原文地址:https://www.cnblogs.com/chuanlong/p/2745370.html
Copyright © 2011-2022 走看看