zoukankan      html  css  js  c++  java
  • 康托展开与八数码问题

    康托展开的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai为当前未出现的元素中是排在第几个(从0开始)。

    用康托展开将排列对应为整数 即这个排列在所有排列中的字典序


    举个例子来说明一下:

    例如,有一个数组 s = ["A", "B", "C", "D"],它的一个排列 s1 = ["D", "B", "A", "C"],现在要把 s1 映射成 X。

    n 指的是数组的长度,也就是4,所以

    X(s1) = a4*3! + a3*2! + a2*1! + a1*0!

    关键问题是 a4、a3、a2 和 a1 等于什么?


    a4 = "D" 这个元素在子数组 ["D", "B", "A", "C"] 中是第几大的元素。"A"是第0大的元素,"B"是第1大的元素,"C" 是第2大的元素,"D"是第3大的元素,所以 a4 = 3。
    a3 = "B" 这个元素在子数组 ["B", "A", "C"] 中是第几大的元素。"A"是第0大的元素,"B"是第1大的元素,"C" 是第2大的元素,所以 a3 = 1。
    a2 = "A" 这个元素在子数组 ["A", "C"] 中是第几大的元素。"A"是第0大的元素,"C"是第1大的元素,所以 a2 = 0。
    a1 = "C" 这个元素在子数组 ["C"] 中是第几大的元素。"C" 是第0大的元素,所以 a1 = 0。(因为子数组只有1个元素,所以a1总是为0)

    所以,X(s1) = 3*3! + 1*2! + 0*1! + 0*0! = 20

    八数码解法一:广搜+哈希

      考虑到费时主要在STL,对于大规模的遍历,用到了ST的set和string,在效率上的损失是很大的,因此,现在面临一个严重的问题,必须自己判重,为了效率,自然是自己做hash。有点麻烦,hash函数不好想,实际上是9!种排列,需要每种排列对应一个数字。网上搜索,得知了排列和数字的对应关系。取n!为基数,状态第n位的逆序值为哈希值第n位数。对于空格,取其为9,再乘以8!。例 如,1 3 7 24 6 9 5 8 的哈希值等于:0*0! + 2*1! + 0*2! + 1*3! + 3*4! +1*5! + 0*6! + 1*7! + 0*8! <9!具体的原因可以去查查一些数学书,其中1 2 34 5 6 7 8 9 的哈希值是0 最小,9 8 7 6 54 3 2 1 的哈希值是(9!-1)最大。而其他值都在0 到(9!-1) 中,且均唯一。然后去掉一切STL之后,甚至包括String之后,得到单向广搜+Hash的代码,算法已经可以在三秒钟解决问题,可是还是不够快!POJ时限是1秒,后来做了简单的更改,将路径记录方法由字符串改为单个字符,并记录父节点,得到解,这次提交,266ms是解决单问题的上限。当然,还有一个修改的小技巧,就是逆序对数不会改变,通过这个,可以直接判断某输入是否有可行解。由于对于单组最坏情况的输入,此种优化不会起作用,所以不会减少单组输入的时间上限。

  • 相关阅读:
    PHP中获取当前页面的URL信息
    $_POST和$GLOBALS['HTTP_RAW_POST_DATA'] 的区别
    curl模拟ip和来源进行网站采集的实现方法
    mysql修改root密码的几种方法
    微信小程序实现支付功能
    git获取远程服务器的指定分支
    mysql函数技巧整理
    sql 查询目标数据库中所有的表以其关键信息
    SET NOCOUNT ON
    C# CultureInfo中常用的InvariantCulture
  • 原文地址:https://www.cnblogs.com/zeze/p/6209538.html
Copyright © 2011-2022 走看看