题目大意

给定一个由数字组成的#字型网格,和一定的移动规则,问最少需要多少次移动才能达到要求的结果。

题目分析

要求最少需要几步到达结果,可以考虑广度优先搜索算法,或者迭代加深深度优先搜索(IDA*),这里使用IDA*算法。 
    在剪枝的时候: 
1. 考虑估价函数H(),表示当前中间八个格子中最少需要移动多少次才能相同(即8 - 
相同数字最多的个数); 
2. 前后两次移动不同为逆操作(即同一列,但不同方向) 
3. 不能连续7次进行移动同一列,且同一方向 
详细见 CanCut 函数。

实现(c++)

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #define MAX(a, b) a>b? a :b
  4. #define MAX_STEP 1000
  5. int gOrderMoved[MAX_STEP];
  6. int gIrreleventQueuee[4] = { 1, 0, 3, 2 };
  7.  
  8. int gCell[25];
  9. int gCellIndexInQueue[4][7];
  10. int gMoveOrder[4][2] = { { 0, 5 }, { 1, 4 }, { 7, 2 }, { 6, 3 } };
  11. int gMoveQueue[8] = {0, 1, 2, 3, 1, 0, 3, 2};
  12. int gMoveDir[8] = {0, 0, 1, 1, 1, 1, 0, 0};
  13. int gCenterCellIndex[8] = { 6, 7, 8, 11, 12, 15, 16, 17 };
  14. int gMinStep;
  15. void Init(){
  16. gCellIndexInQueue[0][0] = 0;
  17. gCellIndexInQueue[0][1] = 2;
  18. gCellIndexInQueue[0][2] = 6;
  19. gCellIndexInQueue[0][3] = 11;
  20. gCellIndexInQueue[0][4] = 15;
  21. gCellIndexInQueue[0][5] = 20;
  22. gCellIndexInQueue[0][6] = 22;
  23.  
  24. gCellIndexInQueue[1][0] = 1;
  25. gCellIndexInQueue[1][1] = 3;
  26. gCellIndexInQueue[1][2] = 8;
  27. gCellIndexInQueue[1][3] = 12;
  28. gCellIndexInQueue[1][4] = 17;
  29. gCellIndexInQueue[1][5] = 21;
  30. gCellIndexInQueue[1][6] = 23;
  31.  
  32. for (int i = 0; i < 7; i++){
  33. gCellIndexInQueue[2][i] = 4 + i;
  34. }
  35.  
  36. for (int i = 0; i < 7; i++){
  37. gCellIndexInQueue[3][i] = 13 + i;
  38. }
  39. }
  40.  
  41. bool IsCenterSame(){
  42. int num = gCell[6];
  43. for (int i = 0; i < 8; i++){
  44. if (gCell[gCenterCellIndex[i]] != num){
  45. return false;
  46. }
  47. }
  48. return true;
  49. }
  50.  
  51. void Rotate(int order){
  52. int move_queue = gMoveQueue[order];
  53. int move_dir = gMoveDir[order];
  54. int tmp;
  55. if (move_dir == 0){
  56. tmp = gCell[gCellIndexInQueue[move_queue][0]];
  57. for (int i = 0; i < 6; i++)
  58. gCell[gCellIndexInQueue[move_queue][i]] = gCell[gCellIndexInQueue[move_queue][i + 1]];
  59. gCell[gCellIndexInQueue[move_queue][6]] = tmp;
  60. }
  61. else{
  62. tmp = gCell[gCellIndexInQueue[move_queue][6]];
  63. for (int i = 6; i > 0; i--)
  64. gCell[gCellIndexInQueue[move_queue][i]] = gCell[gCellIndexInQueue[move_queue][i - 1]];
  65. gCell[gCellIndexInQueue[move_queue][0]] = tmp;
  66. }
  67. }
  68.  
  69. int GetH(){
  70. int count[4] = { 0, 0, 0, 0 };
  71. for (int i = 0; i < 8; i++){
  72. count[gCell[gCenterCellIndex[i]]] ++;
  73. }
  74. int max = MAX(count[1], count[2]);
  75. max = MAX(max, count[3]);
  76. return 8 - max;
  77. }
  78.  
  79. bool CanCut(int moved_step, int next_order){
  80. if (moved_step == 0){
  81. return false;
  82. }
  83. int k = moved_step - 1;
  84. int next_queue = gMoveQueue[next_order];
  85. int next_dir = gMoveDir[next_order];
  86.  
  87. int irrelevent_queue = gIrreleventQueuee[next_queue];
  88. int same_order_count = 0;
  89. while (k >= 0){
  90.  
  91. if (same_order_count >= 6)
  92. return true;
  93.  
  94. while (k >= 0 && gMoveQueue[gOrderMoved[k]] == irrelevent_queue){
  95. k--;
  96. }
  97. if (k < 0){
  98. return false;
  99. }
  100. int queue = gMoveQueue[gOrderMoved[k]];
  101. int dir = gMoveDir[gOrderMoved[k]];
  102. if (queue == next_queue){
  103. if (dir != next_dir){
  104. return true;
  105. }
  106. else{
  107. same_order_count++;
  108. }
  109. }
  110. else{
  111. return false;
  112. }
  113.  
  114. k--;
  115. }
  116.  
  117. return false;
  118. }
  119. void MoveToCenterSame(int moved_step, bool *moved_same){
  120. if (*moved_same){
  121. return;
  122. }
  123. if (IsCenterSame()){
  124. for (int i = 0; i < gMinStep; i++){
  125. printf("%c", 'A' + gOrderMoved[i]);
  126. }
  127. if (gMinStep == 0){
  128. printf("No moves needed");
  129. }
  130. printf("\n");
  131. printf("%d\n", gCell[6]);
  132. *moved_same = true;
  133. return;
  134. }
  135. if (moved_step + GetH() > gMinStep){
  136. return;
  137. }
  138. for (int next_order = 0; next_order < 8; next_order++){
  139. if (CanCut(moved_step, next_order)){
  140. continue;
  141. }
  142. if (*moved_same){
  143. return;
  144. }
  145. gOrderMoved[moved_step] = next_order;
  146. Rotate(next_order);
  147. MoveToCenterSame(moved_step + 1, moved_same);
  148. int reback_order = gMoveOrder[gMoveQueue[next_order]][! gMoveDir[next_order]];
  149. Rotate(reback_order);
  150. }
  151.  
  152. }
  153.  
  154. void Solve(){
  155. gMinStep = 0;
  156. while (true){
  157. bool moved_same = false;
  158. MoveToCenterSame(0, &moved_same);
  159. if (moved_same){
  160. break;
  161. }
  162. gMinStep++;
  163. }
  164. }
  165.  
  166. int main(){
  167. Init();
  168. while (true){
  169. scanf("%d", gCell);
  170. if (gCell[0] == 0){
  171. break;
  172. }
  173. for (int i = 1; i < 24; i++){
  174. scanf("%d", gCell + i);
  175. }
  176. Solve();
  177.  
  178. }
  179. return 0;
  180. }

poj_2286 IDA*的更多相关文章

  1. 逆向工程 - Reveal、IDA、Hopper、HTTPS抓包 等

    目录: 一. iOS 如何做才安全 二.ipa文件 三.沙盒 中的数据 四.Reveal:查看 任何APP 的UI结构 五.反编译工具:IDA 六.反编译工具:Hopper Disassembler ...

  2. IDA的脚本IDC的一个简单使用

    目的:主要是想学习一下IDA的IDC的脚本的使用.这里做了一个小的测试. 这里使用的是VS2015Community来生成文件的. 一.编写测试程序: 这里先生成我们的目标数据. 然后编写测试程序.得 ...

  3. 安卓动态调试七种武器之孔雀翎 – Ida Pro

    安卓动态调试七种武器之孔雀翎 – Ida Pro 作者:蒸米@阿里聚安全 0x00 序 随着移动安全越来越火,各种调试工具也都层出不穷,但因为环境和需求的不同,并没有工具是万能的.另外工具是死的,人是 ...

  4. iOS程序逆向Mac下常用工具——Reveal、HopperDisassemble、IDA

    原文在此 一.Reveal 1 一般使用     Reveal是ITTY BITTY发布的UI分析工具,可以很直观的查看App的UI布局.如下图所示:     Reveal是需要付费的,需要89美元, ...

  5. IDA插件栈字符串识别插件

    该插件是一款可以自动识别栈上局部变量为字符串的插件,字符串形式如下,并自动的加上注释                                       如图:可以自动识别栈上的字符串 项目主 ...

  6. Android动态方式破解apk进阶篇(IDA调试so源码)

    一.前言 今天我们继续来看破解apk的相关知识,在前一篇:Eclipse动态调试smali源码破解apk 我们今天主要来看如何使用IDA来调试Android中的native源码,因为现在一些app,为 ...

  7. 计算机病毒实践汇总六:IDA Pro基础

    在尝试学习分析的过程中,判断结论不一定准确,只是一些我自己的思考和探索.敬请批评指正! 1. IDA使用 (1)搜索.下载并执行IDA Pro,对可执行程序lab05-01.dll进行装载,分别以图形 ...

  8. IDA在内存中dump出android的Dex文件

    转载自http://drops.wooyun.org/tips/6840 在现在的移动安全环境中,程序加壳已经成为家常便饭了,如果不会脱壳简直没法在破解界混的节奏.ZJDroid作为一种万能脱壳器是非 ...

  9. IDA来Patch android的so文件

    在上文中,我们通过分析定位到sub_130C()这个函数有很大可能性是用来做反调试检测的,并且作者开了一个新的线程,并且用了一个while来不断执行sub_130C()这个函数,所以说我们每次手动的修 ...

随机推荐

  1. 【C#/WPF】调节图像的HSL(色相Hue、饱和度Saturation、明亮度Lightness)

    先说概念: HSL是一种描述颜色的方式,其他颜色描述方式还有大家熟悉的RGB值.HSL三个字母分别表示图像的Hue色相.Saturation饱和度.Lightness明亮度. 需求: 制作一个面板,包 ...

  2. strerror() 和perror()函数

    在linux编程中,strerror()是个好东东,因为一个孤零零的errno看不出个所以然,然而strerror()返回的错误描述已经给我们解决问题提供了80%的成功率.但从安全性的角度来讲,str ...

  3. HAProxy+Varnish+LNMP实现高可用负载均衡动静分离集群部署

    HAProxy高可用负载均衡集群部署 基本信息: 系统平台:VMware WorkStation 系统版本: CentOS Linux release 7.2.1511 (Core) 内核版本: 3. ...

  4. Mac下删除安装的pkg

        Mac下的安装和删除都比windows更加简单清晰,这点在dmg方式下非常明显,但很多时候我们会使用pkg来进行安装,这样的安装想删除就有点麻烦了. 比如,我安装了Golang这个pkg用于g ...

  5. 周末大礼:jQuery技巧总结

    一.简介 1.1.概述 随着WEB2.0及ajax思想在互联网上的快速发展传播,陆续出现了一些优秀的Js框架,其中比较著名的有Prototype.YUI.jQuery.mootools.Bindows ...

  6. BCM_I2C函数更改

    版本:sdk-xgs-robo- 平台:BCM53344 应用:控制POE芯片 描述:POE控制芯片使用PD69200,使用i2c与其通信,每次需要发送15字节数据,并接受15字节的返回数据. 1.更 ...

  7. 调用ffmpeg库编译时出现common.h:175:47: error: 'UINT64_C' was not declared in this scope

    解决办法 出现错误:jni/ffmpeg/libavutil/common.h:175:47: error: 'UINT64_C' was not declared in this scope 解决: ...

  8. jquery 中json数组的操作(转)

    在jquery中处理JSON数组的情况中遍历用到的比较多,但是用添加移除这些好像不是太多. 今天试过json[i].remove(),json.remove(i)之后都不行,看网页的DOM对象中好像J ...

  9. nodejs基础 -- 模块系统

    为了让nodejs的文件可以相互调用,nodejs提供了一个简单的模块系统. 模块:是nodejs应用程序的基本组成部分,文件和模块一一对应.即,一个nodejs文件就是一个模块,这个文件可能是jav ...

  10. nodejs基础 -- NPM 使用介绍

    npm:是nodejs的包管理工具,随NodeJS一起安装的,能解决NodeJS代码部署上的很多问题,如: 1.允许用户从NPM服务器下载别人编写的第三方包到本地使用. 2.允许用户从NPM服务器下载 ...