• P1242 新汉诺塔


    题目描述

    设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号。将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A、B、C,这个状态称为初始状态。

    现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态。

    移动时有如下要求:

    ·一次只能移一个盘;

    ·不允许把大盘移到小盘上面。

    输入输出格式

    输入格式:

    文件第一行是状态中圆盘总数;

    第二到第四行分别是初始状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号;

    第五到第七行分别是目标状态中A、B、C柱上圆盘的个数和从上到下每个圆盘的编号。

    输出格式:

    每行一步移动方案,格式为:move I from P to Q

    最后一行输出最少的步数。

    输入输出样例

    输入样例#1: 
    5
    3 3 2 1
    2 5 4
    0
    1 2
    3 5 4 3
    1 1
    输出样例#1: 
    move 1 from A to B
    move 2 from A to C
    move 1 from B to C
    move 3 from A to B
    move 1 from C to B
    move 2 from C to A
    move 1 from B to C
    7

    说明

    圆盘总数≤45

    每行的圆盘描述是从下到上的圆盘编号

    Solution:

      最近太蠢了,打了个爆搜,爆$0$`~`。。。

      正解思路实在是巧妙,我们处理出每个盘的起始位置和目标位置,然后贪心的想到,我们应该从大到小让盘依次移到目标位置,移动过程中就是让小盘让路(即移到另一个中间盘上),然后每次就层层递归,输出就好了。(怎么会有这么巧的思路~)

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=55;
    int n,fr[N],to[N],ans;
    string s="ABC";
    
    il void dfs(int u,int v){
        if(fr[u]==v)return;
        Bor(i,1,u-1) dfs(i,6-fr[u]-v);
        printf("move %d from %c to %c
    ",u,s[fr[u]-1],s[v-1]);
        fr[u]=v,ans++;
    }
    
    int main(){
        cin>>n;
        int t,x;
        For(i,1,3){
            cin>>t;
            while(t--)cin>>x,fr[x]=i;
        }
        For(i,1,3){
            cin>>t;
            while(t--)cin>>x,to[x]=i;
        }
        Bor(i,1,n) dfs(i,to[i]);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    Python中的结构化数据分析利器-Pandas简介
    A great tutorial with Jupyter notebook for ML beginners
    快速修改Matlab默认启动路径(Windows/Mac)
    十大opengl教程
    vtk 基础概念
    OpenGL入门学习
    glut glew区别
    测试程序
    说说C语言运算符的“优先级”与“结合性”
    c++ ACM常用函数
  • 原文地址:https://www.cnblogs.com/five20/p/9138583.html
Copyright © 2020-2023  润新知