菜鸡学C语言之混凝土(四柱汉诺塔)

题目描述

四根柱子的汉诺塔问题,初始有nn个盘子在A柱,小盘子在上,大盘子在下。

要把所有盘子移到D柱上,一次只能移动一个盘子到另一个柱子上,任何时刻不能有大盘子放在小盘子上。

对于每个询问,输出最少的移动次数。

输入

第一行一个整数t(1≤t≤10)表示数据组数

接下来tt行,每行一个整数x(0≤x≤65535),表示每一组询问。

假设上一次询问的答案为yy,则此次询问的盘子数n=(x×y%16)+1,(规定第一组询问的y为10)

输出

对于每组数据,输出一行,一个整数,表示此次询问的最少移动次数

输入样例

2
5
10

输出样例

5
5

样例解释

对于第一组数据,y=10,x=5,n=(10×5%16)+1=3,答案为55。

对于第二组数据,y=5,x=10,n=(5×10%16)+1=3,答案为55。

题目链接:

https://buaacoding.cn/problem/2066/index

题目分析:

这是道四柱汉诺塔的题,在本菜鸡看到此题时隐隐约约觉得这道题我做不出来(滑稽)。

要做出本题,首先要清楚两点:

1. 三柱汉诺塔最少移动次数的结论

2. 四柱汉诺塔最少移动次数的策略

关于多柱汉诺塔的问题,大家在网上一搜都可以搜到,甚至还可以发现有论文专门研究多柱汉诺塔的最短路径问题,我在百度多柱汉诺塔的过程中发现一篇非常不错的推文:https://www.cnblogs.com/liudehao/p/4114414.html

看完推文后,你要做出本题,至少可以清楚上面两点的结论了。

1. 三柱汉诺塔最少移动次数的结论:2^n - 1

2. 四柱汉诺塔最少移动次数的策略:

(1)用4柱汉诺塔算法把A柱上部分的n- r个碟子通过C柱和D柱移到B柱上【F( n- r )步】。
(2)用3柱汉诺塔经典算法把A柱上剩余的r个碟子通过C柱移到D柱上【2^r-1步】。
(3)用4柱汉诺塔算法把B柱上的n-r个碟子通过A柱和C柱移到D柱上【F(n-r)步】。
(4)依据上边规则求出所有r(1≤r≤n)情况下步数f(n),取最小值得最终解。

#include<stdio.h>
int min(int x, int y){
    return x < y ? x : y;
}
int hanoi3(int n){
    return (1 << n) - 1;  // 三柱汉诺塔最短移动次数的结论  
}
int hanoi4(int n){
    if(n == 0)
        return 0;
    if(n == 1)
        return 1;
    int ans = 0x7fffffff;  // 初始化为int范围的最大值
    int i;
    for(i = 1; i <= n; i++)
        ans = min(ans, 2 * hanoi4(n - i) + hanoi3(i));
    return ans;
}
int main(){
    int t, i, ans;
    int x, y = 10, n;
    scanf("%d", &t);
    while(t--){
        scanf("%d", &x);
        n = (x * y % 16) + 1;
        ans = hanoi4(n);
        printf("%d
", ans);
        y = ans;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/flying-rabbit/p/10798853.html