zoukankan      html  css  js  c++  java
  • 魔方——操作阶数实验

    这是我徒弟请教我的一个问题,是一个C++的作业题,题目是:
      从一个已复原的魔方开始,重复某一个操作序列,必然会在有限次重复操作之后又复原,设计程序,输入任意一个操作序列,输入它的复原重复次数。
      操作有18个:
      L,L',L":分别为左面顺时针转90度、逆时针转90度和180度翻转;
      R,R',R":分别为右面顺时针转90度、逆时针转90度和180度翻转;
      T,T',T":分别为顶面顺时针转90度、逆时针转90度和180度翻转;
      D,D',D":分别为底面顺时针转90度、逆时针转90度和180度翻转;
      F,F',F":分别为前面顺时针转90度、逆时针转90度和180度翻转;
      B,B',B":分别为背面顺时针转90度、逆时针转90度和180度翻转。
      在实验报告中记录如下事项:
      输入L,则输出4。
      输入L",则输出2。
      输入D" R,则输出30。
      输入D R,则输出105。以及其它自定的操作序列。
      ======================================================================
      
      看到这个题目,感觉尽管自觉不难,但是编码上一定要有很大的技巧性。我设想魔方一共有六个面,保持它的中心不动不旋转,那么每个面的中间一格也是永远不动的,而周围8个格子随着操作而变换。因此我用这样一个数组 cells[6][8], 来记录六个面。每个面有8个格子,我按照从正上方看过去顺时针方向对这8个格子编排索引。如下图(图中格子上的数字代表它在自己所在面的数组中的索引):

        

      解题的过程实际上就是魔方的旋转建模,因此我们继续完成这个模型。我们考虑上面描述的所有操作本质上都属于以一个主平面旋转,同时影响与它相邻的四个面的边缘三个格子。因此我们引入一个辅助函数:(getinfo) 用来对每一种旋转获取一个角度值和主旋转面,四个受影响面,并把面的索引存放到参数指定的数组中。
      然后我们针对旋转写一个函数:rotate;它根据三种角度,完成(1)对主旋转面的内部旋转;(2)对四个受影响面的格子轮换;
      最后我完成的C代码如下:

      
    Code_magicCube

      总结一下,上面的代码中,主旋转面的旋转已经被统一起来。对4个受影响面的格子的交换代码还是略显 “hard” 和“笨拙”,自觉感觉还是有改进的余地。因为四个受影响面中,每个面提供三个格子,连接组成了一个环形(共12个格子),因此我们可以用一个char[12]线性数组去完成相应的旋转,而且我们看到,针对特定主旋转面,其他12个元素在各自面内的索引相同,这就为我们改进这部分硬代码提供了理论保证。因此我们的getinfo的任务不变,还是需要提供4个受影响面,然后就可以把cells从二维数组看作一格一维线性表,根据面索引和格子索引在cells中定位到这个元素,然后把这12个元素作一个相应角度的轮转即可。这将把对4个受影响面的旋转也统一起来,从而使上面代码进一步简化。有时间的时候我将补充改进后的代码。

  • 相关阅读:
    Spring boot 基于注解方式配置datasource
    Java任务调度框架之分布式调度框架XXL-Job介绍
    mysql使用联合索引提示字符长度超限制解决办法
    程序访问一个地址时候报400错误,浏览器访问正常怎么解决
    JDK8stream将list转Map对象报错java.lang.IllegalStateException
    如何应对互联网行业的「中年危机」?
    SpringMVC访问出错No converter found for return value of type
    怎么设置tomcat在get请求的中文也不乱码?两种情况下配置
    使用tomcat方式实现websocket即时通讯服务端讲解
    服务端向客户端推送消息技术之websocket的介绍
  • 原文地址:https://www.cnblogs.com/hoodlum1980/p/1575339.html
Copyright © 2011-2022 走看看