汉诺塔(记录每种路径次数)

https://ac.nowcoder.com/acm/contest/3004/I

题意:输出汉诺塔移动过程中每一种移动的次数和移动总数。

如下
A->B:XX
A->C:XX
B->A:XX
B->C:XX
C->A:XX
C->B:XX
SUM:XX

解法:记忆化搜索,当前状态的可以由上一状态得到。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <string>
#include <stdio.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
#define mod 998244353
#define PI acos(-1)
using namespace std;
typedef long long ll ;
const int maxn = 110;
int n , m , k , t;
struct node{
    ll ab , ac , ba , bc , ca , cb;
}dp[maxn];

bool vis[maxn];

node hanio(int n , int a,  int b , int c){
    if(vis[n]) return dp[n];
    node x = hanio(n-1 , a , c , b);
    dp[n].ab += x.ac;
    dp[n].ac += x.ab;
    dp[n].ba += x.ca;
    dp[n].ca += x.ba;
    dp[n].bc += x.cb;
    dp[n].cb += x.bc;

    dp[n].ac++;
    x = hanio(n-1 , b , a , c);
    dp[n].ab += x.ba;
    dp[n].ac += x.bc;
    dp[n].ba += x.ab;
    dp[n].ca += x.cb;
    dp[n].bc += x.ac;
    dp[n].cb += x.ca;

    vis[n] = 1;
    return dp[n];
}

int main()
{
    vis[1] = 1 ;
    dp[1].ab = dp[1].ba = dp[1].bc = dp[1].ca = dp[1].cb = 0;
    dp[1].ac = 1 ;
    int n ; cin >> n;
    hanio(n , 1 , 2 , 3);
    ll sum = (1ll<<n)-1ll;
    cout << "A->B:" << dp[n].ab << endl;
    cout << "A->C:" << dp[n].ac << endl;
    cout << "B->A:" << dp[n].ba << endl;
    cout << "B->C:" << dp[n].bc << endl;
    cout << "C->A:" << dp[n].ca << endl;
    cout << "C->B:" << dp[n].cb << endl;
    cout << "SUM:" << sum << endl;
    return 0 ;
}

也可打表找规律。

原文地址:https://www.cnblogs.com/nonames/p/12293656.html

时间: 2024-10-10 09:10:41

汉诺塔(记录每种路径次数)的相关文章

C++ 汉诺塔问题

汉诺塔问题,是心理学实验研究常用的任务之一.当然我们是学计算机的,因此我们尝试用计算机去求解它. 例题 openjudge6261 汉诺塔问题 描述 有一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由n个圆盘构成的塔.目的是将最左边杆上的盘全部移到中间的杆上,条件是一次只能移动一个盘,且不允许大盘放在小盘的上面.这就是著名的汉诺塔问题. 假定圆盘从小到大编号为1,2,3,-- 输入 输入为一个整数后面跟三个单字符字符串. 整数为盘子的数目,后三个字符表示三个杆子的编号

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柱上的盘的盘号系

HDU1996 汉诺塔VI 【递推】

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

汉诺塔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个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从

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个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从

HDU 1996 汉诺塔VI

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1996 n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于 发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱 子从下往上的大小仍保持如下关系 : n=m+p+q a1>a2>...>am b1>b2>...>bp c1>c2>...>cq 计算所有会产生的系列总数. Input包含多组数据,

汉诺塔VI

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

ACM_汉诺塔问题(水)

Problem Description: 最近小G迷上了汉诺塔,他发现n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 : n=m+p+q a1>a2>...>am b1>b2>...>bp c1>c2>...>cq 小G希望聪明的你能告诉他所有会产生的系列总数. Input: 输入一个N,N<30

ID 1996 汉诺塔VI

Problem Description n个盘子的汉诺塔问题的最少移动次数是2^n-1,即在移动过程中会产生2^n个系列.由于发生错移产生的系列就增加了,这种错误是放错了柱子,并不会把大盘放到小盘上,即各柱子从下往上的大小仍保持如下关系 : n=m+p+q a1>a2>...>amb1>b2>...>bpc1>c2>...>cq计算所有会产生的系列总数. Input 包含多组数据,首先输入T,表示有T组数据.每个数据一行,是盘子的数目N<30.