万恶之源

优秀题解

用文字终究难以穷尽代码的思想

思路

每次操作都有八种选择,相当于一棵每次延申八个子节点的搜索树,故搜索应该是一种方法。而这题要求求最少步数,我们就可以想到可以试试迭代加深搜索(但其实我做它因为它是书本的习题)。再搭配一个估值函数来剪枝就很香啦。

轮换方块(操作打表)

我的原始思路十分粗暴,就是用一个二维数组来存储这个“#”图形,但是这会十分浪费空间,在写轮换操作时的代码时也很繁冗。

我学到的呢,是用一维数组来存储这个图形,也就是直接用题目的输入生成一个数组。这样进行轮换操作可能不如二维的直观,但熟悉熟悉就好吧。所以应该如何轮换呢?这其实相当于一个映射,由于每个元素在原来的图形的位置是独特的,那将原图形一维化之后,这个元素的位置也仍然是独特的。因此,我们只需要找出,原来“#”图形的某一列/行在一维数组的对应坐标就好。

但是由于数据规模不大,我们可以打表来实现,也就是事先找出某个操作需要使用的坐标。

const int index[8][7] = {  //从A-H操作变动的下标
{ 0,2,6,11,15,20,22 }, //A
{ 1,3,8,12,17,21,23 }, //B
{ 10,9,8,7,6,5,4 }, //C
{ 19,18,17,16,15,14,13 }, //D
{ 23,21,17,12,8,3,1 }, //E
{ 22,20,15,11,6,2,0 }, //F
{ 13,14,15,16,17,18,19 }, //G
{ 4,5,6,7,8,9,10 }, //H
};

可行性剪枝(估值函数)

再做这题之前我做了另外一题,HDU - 1560 - DNA sequence,这题估计的是剩余还需要处理的长度,本题估计的则是剩余还需要处理的方格(冥冥之中总感觉有相似之处)。

估计方格

因为每次轮换,最多只会引进一个目标元素(直观感受),因此,还需要处理的方格(即上文需要估计的量),就等于中心元素中,不为目标元素的元素的个数,也就是非目标元素的个数。一旦目标元素确定那计数就小菜一碟啦,但是我们怎么知道我们的目标是什么?

目标元素

我的原始思路是,开局在中心元素个数最多的即我们的目标,但是想了想说不定人家也可能一手好牌打得稀烂(结果确实存在这种情况,开始在中间最多的并不是正解),于是我最后决定还是得枚举目标,但是我总感觉开始在中间最多的越有可能是正确答案,于是按照出现的次数排序来进行枚举,搜索。(但事实证明这并没有必要,而且写出来的效果就很让人怀疑,一个问题居然要搜索三次)

做完之后我参考了一下其它题解,发现了一种更好的思路。我们完全可以作一棵没有目标的墙头草,谁最多我们就往哪倒。也就是说,我们可以计算在中间1,2,3这三个元素的个数的最大值,一旦这个计算结果等于8,我们就完成了任务!这时再去检查是谁达到了这个数字即可。(另外这样能够保证我们的结果就是最优解,按我的原始思路,很有可能出现三组解(一个搜索一个解),还需要对这三组解进行进一步的比较)

重大问题

  1. cnt()函数——估计哪个数字应该优先搜索。

在排序时思路不对,导致三个数字不能正常被排序与标记。

(我有时觉得这个函数没有用,事实上确实没有用,还徒增很多烦恼)

  1. 搜索时忘了有H这一操作。。。甚至在很后面才发现。。。

打印出每次的操作,发现只有7种操作,那就可以发现这个bug了,或者是分析出错的样例,然后分析为什么没有出现某个路径,然后再定位到拓展叶子节点的代码,应该可以发现这个bug

  1. 没有仔细审题 || 没有考虑特殊情况——No moves needed

If no moves are needed, output "No moves needed",为什么说它严重呢,因为这将导致对拍完全没有问题,但是交上去就是WA。-__-

以后做题一定要特例先行!

  1. 没有意识到1, 2, 3都有可能成为最后的答案,即使某一个数在中心的个数最少。

这个其实反而是最开始的想法,但做着做着题就认为中间数量最多的就是最后答案。。。还是考虑的不够全面啊

  1. 最后的判断依据

接着第四点,由于任何一个数都有可能成为答案,最后的判断依据应该是在某个深度下,谁的操作路径字典序最小。并且,这里面还要考虑到如果一个路径不存在,它的长度可能是最小的(string,长度为0)判断完之后,最后还得输出中心元素,这两个操作如何协调,也是一个麻烦的问题。

  1. 尝试用map储存状态

这会导致TLE==,感觉可能是状态太多了,希望以后的自己能对这个问题有更多理解,最好还能提出解决的办法。

  1. 代码十分冗杂,同时时间开销非常大,一定要学习优秀的代码

我的思路从一开始就不太正确,以至于后面花费了相当多的精力去给它修修补补。导致了这种情况的发生。

一点感悟

方向错误也不是第一次了,每当出现这种情况,我就会想起托勒密,他穷尽他的心血将地心说完善得几乎完美,但终究在一开始他便错了。但是他的错误也给后人带来的启示与借鉴,我也希望我的每一次错误都能够给日后的我或看到这篇文章的人们提供一种信息,某条路是不行的,帮助他们少走弯路,以上。

IDA*、操作打表、并行处理-The Rotation Game HDU - 1667的更多相关文章

  1. IDA 操作记录

    IDA 操作记录 1.加载文件 windows 下,用ida加载文件后,会在该文件同目录下生成几个文件,含义如下: .id0 : 二叉树数据库 .id1:    文件包含描述每个程序字节的标记 .na ...

  2. EF Codefirst 多对多关系 操作中间表的 增删改查(CRUD)

    前言 此文章只是为了给新手程序员,和经验不多的程序员,在学习ef和lambada表达式的过程中可能遇到的问题. 本次使用订单表和员工表建立多对多关系. 首先是订单表: public class Ord ...

  3. JAVASE02-Unit05: 集合操作 —— 查找表

    Unit05: 集合操作 -- 查找表 使用该类测试自定义元素的集合排序 package day05; /** * 使用该类测试自定义元素的集合排序 * @author adminitartor * ...

  4. JAVASE02-Unit04: 集合框架 、 集合操作 —— 线性表

    Unit04: 集合框架 . 集合操作 -- 线性表 操作集合元素相关方法 package day04; import java.util.ArrayList; import java.util.Co ...

  5. [转]C#操作注册表

    原文链接:http://www.cnblogs.com/txw1958/archive/2012/08/01/csharp-regidit.html 下面我们就来用.NET下托管语言C#注册表操作,主 ...

  6. [荐]使用Js操作注册表

    使用Js操作注册表 要操作注册表需要通过ActiveX控件调用WScript.shell对象,通过该对象的一些方法来操作. WshShell对象:可以在本地运行程序.操纵注册表内容.创建快捷方式或访问 ...

  7. JS:操作样式表3:内联和外链样式

    var box = document.getElementById("box"); box.style.属性;只能读取修改行内样式. //访问元素样式2,对外链样式表进行操作 do ...

  8. c++ 操作注册表

    1.       注册表简介 注册表是为Windows NT和Windows95中所有32位硬件/驱动和32位应用程序设计的数据文件,用于存储系统和应用程序的设置信息.16位驱动在Winnt (Win ...

  9. .Net操作注册表--un

    C#操作注册表 导入命名空间 Using MicroSoft.Win32;//64位系统装的64位版本

随机推荐

  1. (2)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Cloud是什么?Spring Cloud版本介绍

    ​ Spring Cloud 是一系列框架的有序集合.它利用 Spring Boot 的开发便利性,巧妙地简化了分布式系统基础设施的开发,如服务注册.服务发现.配置中心.消息总线.负载均衡.断路器.数 ...

  2. 【第十九篇】- Maven NetBeans之Spring Cloud直播商城 b2b2c电子商务技术总结

    Maven NetBeans NetBeans 6.7 及更新的版本已经内置了 Maven.对于以前的版本,可在插件管理中心获取 Maven 插件.此例中我们使用的是 NetBeans 6.9. 关于 ...

  3. private关键字理解

    private 意思: 私有的 私人的 不公开的 private 是一个修饰符可以用来修饰成员变量和方法 被private修饰的成员变量或成员方法,只能在本类中访问,针对private修饰的成员变量, ...

  4. 1004. 最大连续1的个数 III

    1004. 最大连续1的个数 III 给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 . 返回仅包含 1 的最长(连续)子数组的长度. 示例 1: 输入:A = ...

  5. Lambda 表达式详解

    目录 前言 预备知识,理解委托的构成 引用实例方法的委托 引用静态方法的委托 Lambda 表达式的实际编译结果 CASE 1 没有捕获任何外部变量的Lambda 表达式 CASE 2 捕获了外部方法 ...

  6. Thinkphp5 主动式 计划任务 支持windows和linux

    百度搜索过相关的php计划任务的资料,特别是搜索thinkphp的计划任务,目前能明确实现的都是被动式的,就是通过tp3.2自带的计划任务类实现,通过挂钩子的形式,用户访问网站的时候就执行计划任务,这 ...

  7. javascript 字符串反转 strip_tags 字符串常用的自定义函数,加载css etc.

    字符串反转 String.prototype.reverse = function() { var a = this.split(''); for (var i = 0, j = a.length-1 ...

  8. 牛客练习赛89E-牛牛小数点【数论】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/11179/E 题目大意 定义\(f(x)\)表示\(\frac{1}{x}\)的混循环节长度(如果没有循环节就 ...

  9. 最详细的搭建web自动化测试网站,别再说你没有实战项目(文未有福利)

    一步步教你搭建开源网站 环境准备: Tomcat shopping商城文件 jdk环境 Mysql环境 解压shopping.rar拷贝至tomcat/webapps 在navicat导入数据库db_ ...

  10. php flush() 页面缓冲及时输出 每隔一秒输出页面输出

    <?php //方案一 ob_end_clean(); echo str_pad('', 1024); // 设置足够大,大过php.ini的output_buffering设置值 for ($ ...