xie 的个人资料追忆似水流年照片日志列表 工具 帮助

日志


3月16日

魔方玩法

贴一个我一朋友的经验介绍,华工牛人哇,四五阶魔方国内最快呀。             

       三阶魔方顶层基本解法(更新版)

                ――四个步骤解决三阶魔方顶层 

              

   解魔方,对一般的初学者,觉得最复杂的就是顶层。急于想学会全部还原,不想多记公式,厌倦步骤多的公式,公式记得不牢固是大多数初学者的心态。为了照顾大多数的初学者,所以在此就给了一种公式少的解法,当然步骤是会多了点,而且每步的情况分析也有点烦,但只要 用心+耐心=成功,一天就足以学会啦!!!

     首先给出这种方法的四个步骤,当然前提还原了第一,二层,步骤如下:

     十字        角反色         换角       换棱(完成)

     下面对每个步骤作具体的介绍。

     十字

所谓十字,就是将顶层做成一个十字架。

           公式:R’U’F’UFR(公式字符说明在后面)

           在没做成十字前,将会遇到多种情况,但都可以分成以下三大类情况:

            1   2  3

        第一种情况用一次公式就可以做成十字;

        第二种情况用二次公式就可以做成十字;

        第三种情况用三次公式就可以做成十字。

 

     角反色:

将顶层所有角的颜色反成和中心块一样的颜色。

             公式分A,B两种基本情况

             公式:(A)角顺时反色:RUR’URU2R’

                   (B)角逆时反色:R’U’RU’R’U2R

             用法:如图: 

角顺时反色(A)                     逆时反色(B)

除了以上两种情况外,还有以下种5种,但者几种都是用上面的公式将其转化成“一个颜色已好,其余三个还没反好”这种情况。

          

   1    2     3     4     5

下面来分析以上五种情况的解法:

(1)       连续用两次“角顺时反色公式”就可以把颜色反好

(2)       用一次“角逆时反色公式”就变成情况B

(3)       用一次“角逆时反色公式”就变成情况A

(4)       先将顶层逆时转过90度(即U’),接着用“角逆时反色公式”就变成情况A

(5)       用一次“角顺时反色公式”就变成情况A

 

换角

根据角的颜色将顶层的四个角的位置换好

      公式:(lU'R)D2(R'UR)D2R’L’

      公式用途:将其中一个角的颜色对好,并把这个对好的角放在左上角,用一次这个公式就是将左下,右上,右下三个角顺时针转动一次。例如:

(对好颜色的角放在左上角)     

换角会碰到以下几种情况:

 一角对好颜色,三个角错位(又分成以下两种情况):

1.其它三个角顺时转就可换好,用一次公式。

        2其它三个角逆时转就可换好,用两次公式。

两角对好颜色,两个角错位(又分成以下两种情况):

        1.邻角错位(如图)

                 用一次公式就可以转化成“一角对好颜色,三个角错位”的情况‘

             2.对角错位(如图)

               用一次公式就可以转化成“邻角错位”的情况。

 

      换棱

就是把中间的四条棱换好

           公式:顺时换棱:(R2' URU)(R'U'R'U')(R'UR')

                 逆时换棱:(R U')RURU)(RU'R'U'R2'

           用法:一条棱已经对好位置,另外三条棱错位。如下图:

              

 顺时换棱            逆时换棱

还有一种情况:就是四条棱都是错位的,这时只要随便用顺或逆时换棱种任一条公式就可以转化为以上两种情况。即一条棱已经对好位置,另外三条棱错位。

附:四条棱都是错位的两种情况:

                                 

r2 (R2 U) r2 (R2 U) U r2 (R2 U) R2 r2        .( R'U') (RU')(RURU' R'URU)(R2U')R'U2

 

尾递归

转载啊
================================================
其实,对一些如树的递归结构,递归算法是又自然又好用。
如果看看一些用来代替递归的技术,(汉诺塔的迭代算法不去说它,那是真正的算法的革命,除了佩服没啥好说的),一般来说只不过是自己模拟堆栈,编起来费劲,读起来费劲,维护起来更费劲。而模拟堆栈的效果,相比于简单的递归,好处在哪里呢?
1。不使用进程堆栈,不会耗尽堆栈空间(虽然可能耗尽堆空间)
2。可以有选择地把真正有用的东西压栈,而不用什么pc, sp, 所有的局部变量都压栈。这样节省了一些内存(不过,仍然在一个数量级,递归是O(N),模拟递归仍然是O(N))。不过这也不绝对,编译器的优化可以识别一些不需要保存的局部变量的。(这叫变量生存期分析) 那么这样做又没有坏处呢?除了上面的代码复杂度的问题(我想很多搞嵌入式系统,实时系统的C高手都对此不屑一顾),还有一个效率上的缺点: 模拟的递归使用堆空间,它的new/delete都比直接在堆栈上分配空间慢得多。而且很容易产生内存碎片。 所以说,模拟堆栈只不过是牺牲了一定的效率来换取了一部分空间而已。是否值得,嘿嘿,就得看具体应用了。 好,闲话说完,下面言归正传。

话说大家都知道函数调用要压栈。不过这是有几个例外的。
1。函数是inline的。
2。语言采用的函数调用方式是continuation, 而不是activation record. 这种模式中语言可以使用堆而不是栈来完成函数调用。
3。尾调用。也就是说,函数调用出现在调用者函数的尾部,因为是尾部,所以根本没有必要去保存任何局部变量,sp, pc的信息。直接让被调用的函数返回时越过调用者,返回到调用者的调用者去。
尾调用优化不是什么很复杂的优化,实际上几乎所有的现代的高级语言编译器都支持尾调用这个很基本的优化。
实现层面上,只需要把汇编代码call改成jmp, 并放弃所有局部变量压栈处理,就可以了。所以,很简单。

于是,就剩下递三条:尾调用。而一个对自己本身的递归尾调用,就叫做尾递归。

那么,当尾递归时,我们就没有前面分析的递归调用的占用堆栈的缺点,因为每次调用都是尾调用,所以堆栈根本就没有被占用,每次调用都是重新使用调用者的堆栈。