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.

  • 相关阅读:
    列"xx"不在表Table中
    asp.net中自定义验证控件
    ASP.NET母版与内容页相对路径的问题
    html点小图看大图最快捷的方法
    ThinkCMF的跳转303 404等页面的方法
    关于ThinkCMF自带插件上传不了图片的解决方法
    js中百分比运算,大型数据会算错
    数据库价格汇总查询的方法
    信息资源5
    操作系统概论
  • 原文地址:https://www.cnblogs.com/chuanlong/p/2745370.html
Copyright © 2011-2022 走看看