SGOI8之《烦恼的设计师》解题报告
   


一、题意简述:

  本题要求将一个边长为3的六边形"阵"(共19个元素)通过一定的规则变换,从初始状态转化为目标状态,并使变换的次数最少。具体规则如下:每次选定除边缘之外的7个元素之一,将其周围的6个元素沿顺时针方向或逆时针方向移动一个位置。输入初始状态和目标状态,输出最少变换次数以及一种是变换次数最少的变换方法。

二、算法分析:

  1. 基本算法:
  本题是比较典型的广度搜索题,且题目中给出了一些重要的信息(一个花坛里摆放的不同种类的花不超过3种,对于任意两种花,数量多的花的盆数至少是数量少的花的2倍)使得状态总量不超过1,058,148个,使得数据的存储量不太大,广度搜索可以胜任。但是如果按照最普通的广度搜索来解题的话,时间上将无法容忍,所以下面将讨论搜索的优化。

  2. 状态表示:
  如果用原题中提供的状态表示存储的话,不但浪费空间(空间开的过大,也会影响时间效率),而且判重也很不方便。首先,因为至多只有三种花,所以将原先花的编号转化为0,1,2;然后将二维数组转化为一维的,将它看成一个19位的3进制数(可以以0开头);再将其转化为10进制数;这样就可以用一个整数来表示一个状态了。

  3. 判重的优化:
  用最一般的逐个比较判重显然是不现实的(状态量大,耗时长),所以应该采用直接判重的方法。但如果开一个的数组判重又存在空间问题,而事实上根本就不需要那么多的状态,实际空间利用率极低,所以就想到用哈希表来优化存储。哈希表是一种用途广泛的数据结构,其实现的方法也很多,本题采用的是拉链的存储方法,哈希函数用的是这个三进制数除以某一个数的余数,效果较好,但不一定是最优的,有兴趣的同学还可以尝试其他方法。

  4. 关于状态转化的说明:
  在对一个状态进行扩展的时候,没必要将10进制数转化为19位3进制数再移动,然后再转回3进制数判重、存储,这样会浪费不少时间。其实,直接进行3进制数的位操作就可以了,具体方法参见表程。

  5. 对选手程序失分的分析:
  本题得分率普遍不高,一般程序都只得到1~2个点甚至许多程序"全军覆没"。究其原因,多是没有对程序进行足够优化所至,有些程序甚至是几乎没有任何优化,当然这可能是与时间不足有关。另外,有一个特殊数据,即初始状态与目标状态相同(输出0即可),许多人没有判断,结果直接导致本题没有得到满分的程序(最好的就只过了9个点,就是没有判断特殊情况!)

三、小结:

  本题在"看懂"题意之后,要得出一个基本算法(即广度搜索)是很容易的事。然而要充分优化,使得时空效率可被接受,却不那么容易了,需要多方面的知识、技巧,如把握题中的重要信息、转化状态表示的方法、优化广度搜索的一般方法、对数据结构的了解(尤其是哈希表的应用)以及对细节的把握等。

   

 
网站导航 | 关于曙光 | 联系我们 | 请提意见
Copyright © FuJian Sunshine Educational Info. Co.,Ltd.
福建曙光教育资讯有限公司 版权所有