【杭电】[1997]汉诺塔VII

文章字数:482

问题描述

问题分析

(1)首先判断是不是已经完全放好了或者还没有开始移动,这样就不用考虑是否最优化了,即所有的盘子在C柱上或者所有的盘子在A柱上,这样是合法的,直接输出true。
(2)【我们考虑盘号最大的盘子第n号盘子,移动方向为A–>C,它只可能在A柱或者C柱上,如果在B柱上我们可以直接返回false–①】;
如果盘号最大的盘子在A柱上,说明其它盘子正在进行A–>B的操作,所以考虑移动的那个n-1个盘子,然后同样按①判断,只不过,最大盘号变成了n-1,而移动方向变成了A–>B;
如果盘号最大的盘子在C柱上,说明其它盘子正在进行B–>C的操作,所以考虑移动的那个n-1个盘子,然后同样按①判断,只不过,最大盘号变成了n-1,而移动方向变成了B–>C;
利用递归按这种方式不断地进行①操作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<stdio.h>
int map[4][100];
int f(int a,int b) {
    if(a==1)
        return b==2?3:2;
    if(a==2)
        return b==1?3:1;
    if(a==3)
        return b==1?2:1;
}
bool judge(int n,int t1,int t2) {
    if(n==0)
        return true;
    for(int i=0; i<map[0][f(t1,t2)]; i++)
        if(map[f(t1,t2)][i]==n)
            return false;
    for(int i=0; i<map[0][t1]; i++)
        if(map[t1][i]==n)
            return judge(n-1,f(t1,t2),t1);
    for(int i=0; i<map[0][t2]; i++)
        if(map[t2][i]==n)
            return judge(n-1,f(t1,t2),t2);
}
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        scanf("%d",&map[0][1]);
        for(int i=0; i<map[0][1]; i++)
            scanf("%d",&map[1][i]);
        scanf("%d",&map[0][2]);
        for(int i=0; i<map[0][2]; i++)
            scanf("%d",&map[2][i]);
        scanf("%d",&map[0][3]);
        for(int i=0; i<map[0][3]; i++)
            scanf("%d",&map[3][i]);
        printf("%s\n",judge(n,1,3)?"true":"false");
    }
    return 0;
}

该内容采用 CC BY-NC-SA 4.0 许可协议。

如果对您有帮助或存在意见建议,欢迎在下方评论交流。

加载中...