HDU2.2.3 (汉诺塔VII)

汉诺塔VII

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1574 Accepted Submission(s): 1123
 

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


Author

[email protected]


Source

ECJTU 2008 Spring Contest


Recommend

lcy

#include<iostream>
using namespace std;
int main()
{
    int a=1,b=2,c=3;
    int h[4][65],n[4],one[4],N;
    int cas;
    cin>>cas;
    while(cas--)
    {
        int flag=0;
        one[a]=one[b]=one[c]=1;
        cin>>N;
        cin>>n[a];
        for(int i=one[a];i<=n[a];i++)
            cin>>h[a][i];
        cin>>n[b];
        for(int i=one[b];i<=n[b];i++)
            cin>>h[b][i];
        cin>>n[c];
        for(int i=one[c];i<=n[c];i++)
            cin>>h[c][i];
        while(1)
        {
            if(n[a]==N||n[c]==N)
            {
                flag=1;break;
            }
            if(n[b]>0&&h[b][one[b]]==N)
            {
                flag=0;break;
            }
            if(n[a]>0&&h[a][one[a]]==N)//交换b和c
            {
                N--;one[a]++;
                n[a]--;
                int t=b;
                b=c;c=t;
                continue;
            }
            if(n[c]>0&&h[c][one[c]]==N)//交换a和b
            {
                N--;one[c]++;
                n[c]--;
                int t=a;
                a=b;b=t;
                continue;
            }
        }
        if(flag)cout<<"true"<<endl;
        else cout<<"false"<<endl;
    }
    return 0;
}
时间: 2024-12-26 11:09:00

HDU2.2.3 (汉诺塔VII)的相关文章

汉诺塔VII(递推,模拟)

汉诺塔VII Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1503 Accepted Submission(s): 1077   Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从

汉诺塔系列问题: 汉诺塔II、汉诺塔III、汉诺塔IV、汉诺塔V、汉诺塔VI、汉诺塔VII

汉诺塔II:(hdu1207) /先说汉若塔I(经典汉若塔问题),有三塔,A塔从小到大从上至下放有N个盘子,如今要搬到目标C上, 规则小的必需放在大的上面,每次搬一个,求最小步数.这个问题简单,DP:a[n]=a[n-1]+1+a[n-1],先把 上面的n-1个放在B上,把最大的放在目标C上,再把N-1个放回到C上就可以. </pre><p></p>如今是汉若塔II,改为四个塔,開始方程想简单了,不是最优的.给出网上的一种最优解法例如以下:(1)将x(1<=x&l

HDU 1997 汉诺塔VII

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1997 Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 : n=m+p+qa1>a2>...>amb1>b2>...>bpc1>c2>...>cqai是A柱上的盘的盘号系

hdu1997 汉诺塔VII(DFS递归调用)

题目详情:传送门 我都要做郁闷了,逻辑一直没错,但是最后一组答案就是过不了.看了几个小时,终于发现问题所在了.我把数组初始化 memset() 函数,放在了自定义函数 Input 中,使用形参的sizeof()作为地址的长度,结果数组没有初始化成功,导致悲剧的诞生.之后我把 memset() 中的地址长度改回数组长度问题终于解决了.刚做这一题时我把它当成栈混洗了,结果一直没琢磨明白.之后在网上一查,恍然大悟.霎时间,感觉好难过,为什么自己就没想到.下面我们来分析一下本题的思路吧. 分析: 这一题

汉诺塔VII

HDU1997  题意:排列汉诺塔需要的最小步数是2^N-1  排列过程中会生成2^N个排列,判断一个序列是否发生了额外的移动步数,也就是完成汉诺塔话费的步数多余2^N-1. 模拟法: 1:在正确的排列中,最大的n盘一定在a或c柱上,否则false 2:如果n在a柱上,剩下n-1个盘处在a->b的过程中 3:如果n在c柱上,剩下n-1个盘处在b->c的过程中 4:重复123直到n=0 可以看出是O(N)的时间复杂度. 1 #include <bits/stdc++.h> 2 usi

水题 第四站 HDU 汉诺塔VII

先来回忆一下汉诺塔 A,B,C,三个塔将A塔上的n块砖转移到C塔,首先将(n-1)块砖转移到B塔,将第n块砖转移到C塔,再将B塔上的(n-1)块砖转移到C塔,所以 函数为借助B塔,将A塔的砖转移到C塔, 首先是借助C塔,将A塔的砖转移到B塔, 然后是借助A塔,将B塔的砖转移到C塔. 附上网上的代码,有助于理解,出处 http://blog.csdn.net/kkkkkxiaofei/article/details/8333644/ 1 #include <iostream> 2 #includ

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

从汉诺塔问题来看“递归”本质

汉诺塔问题 大二上数据结构课,老师在讲解"栈与递归的实现"时,引入了汉诺塔的问题,使用递归来解决n个盘在(x,y,z)轴上移动. 例如下面的动图(图片出自于汉诺塔算法详解之C++): 三个盘的情况: 四个盘的情况: 如果是5个.6个.7个....,该如何移动呢? 于是,老师给了一段经典的递归代码: void hanoi(int n,char x,char y,char z){ if(n == 1) move(x,1,z); else{ hanoi(n-1,x,z,y); move(x,

bzoj1019: [SHOI2008]汉诺塔(dp)

1019: [SHOI2008]汉诺塔 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1739  Solved: 1062[Submit][Status][Discuss] Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的