题目大意

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

题目分析

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

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX(a, b) a>b? a :b
#define MAX_STEP 1000
int gOrderMoved[MAX_STEP];
int gIrreleventQueuee[4] = { 1, 0, 3, 2 }; int gCell[25];
int gCellIndexInQueue[4][7];
int gMoveOrder[4][2] = { { 0, 5 }, { 1, 4 }, { 7, 2 }, { 6, 3 } };
int gMoveQueue[8] = {0, 1, 2, 3, 1, 0, 3, 2};
int gMoveDir[8] = {0, 0, 1, 1, 1, 1, 0, 0};
int gCenterCellIndex[8] = { 6, 7, 8, 11, 12, 15, 16, 17 };
int gMinStep;
void Init(){
gCellIndexInQueue[0][0] = 0;
gCellIndexInQueue[0][1] = 2;
gCellIndexInQueue[0][2] = 6;
gCellIndexInQueue[0][3] = 11;
gCellIndexInQueue[0][4] = 15;
gCellIndexInQueue[0][5] = 20;
gCellIndexInQueue[0][6] = 22; gCellIndexInQueue[1][0] = 1;
gCellIndexInQueue[1][1] = 3;
gCellIndexInQueue[1][2] = 8;
gCellIndexInQueue[1][3] = 12;
gCellIndexInQueue[1][4] = 17;
gCellIndexInQueue[1][5] = 21;
gCellIndexInQueue[1][6] = 23; for (int i = 0; i < 7; i++){
gCellIndexInQueue[2][i] = 4 + i;
} for (int i = 0; i < 7; i++){
gCellIndexInQueue[3][i] = 13 + i;
}
} bool IsCenterSame(){
int num = gCell[6];
for (int i = 0; i < 8; i++){
if (gCell[gCenterCellIndex[i]] != num){
return false;
}
}
return true;
} void Rotate(int order){
int move_queue = gMoveQueue[order];
int move_dir = gMoveDir[order];
int tmp;
if (move_dir == 0){
tmp = gCell[gCellIndexInQueue[move_queue][0]];
for (int i = 0; i < 6; i++)
gCell[gCellIndexInQueue[move_queue][i]] = gCell[gCellIndexInQueue[move_queue][i + 1]];
gCell[gCellIndexInQueue[move_queue][6]] = tmp;
}
else{
tmp = gCell[gCellIndexInQueue[move_queue][6]];
for (int i = 6; i > 0; i--)
gCell[gCellIndexInQueue[move_queue][i]] = gCell[gCellIndexInQueue[move_queue][i - 1]];
gCell[gCellIndexInQueue[move_queue][0]] = tmp;
}
} int GetH(){
int count[4] = { 0, 0, 0, 0 };
for (int i = 0; i < 8; i++){
count[gCell[gCenterCellIndex[i]]] ++;
}
int max = MAX(count[1], count[2]);
max = MAX(max, count[3]);
return 8 - max;
} bool CanCut(int moved_step, int next_order){
if (moved_step == 0){
return false;
}
int k = moved_step - 1;
int next_queue = gMoveQueue[next_order];
int next_dir = gMoveDir[next_order]; int irrelevent_queue = gIrreleventQueuee[next_queue];
int same_order_count = 0;
while (k >= 0){ if (same_order_count >= 6)
return true; while (k >= 0 && gMoveQueue[gOrderMoved[k]] == irrelevent_queue){
k--;
}
if (k < 0){
return false;
}
int queue = gMoveQueue[gOrderMoved[k]];
int dir = gMoveDir[gOrderMoved[k]];
if (queue == next_queue){
if (dir != next_dir){
return true;
}
else{
same_order_count++;
}
}
else{
return false;
} k--;
} return false;
}
void MoveToCenterSame(int moved_step, bool *moved_same){
if (*moved_same){
return;
}
if (IsCenterSame()){
for (int i = 0; i < gMinStep; i++){
printf("%c", 'A' + gOrderMoved[i]);
}
if (gMinStep == 0){
printf("No moves needed");
}
printf("\n");
printf("%d\n", gCell[6]);
*moved_same = true;
return;
}
if (moved_step + GetH() > gMinStep){
return;
}
for (int next_order = 0; next_order < 8; next_order++){
if (CanCut(moved_step, next_order)){
continue;
}
if (*moved_same){
return;
}
gOrderMoved[moved_step] = next_order;
Rotate(next_order);
MoveToCenterSame(moved_step + 1, moved_same);
int reback_order = gMoveOrder[gMoveQueue[next_order]][! gMoveDir[next_order]];
Rotate(reback_order);
} } void Solve(){
gMinStep = 0;
while (true){
bool moved_same = false;
MoveToCenterSame(0, &moved_same);
if (moved_same){
break;
}
gMinStep++;
}
} int main(){
Init();
while (true){
scanf("%d", gCell);
if (gCell[0] == 0){
break;
}
for (int i = 1; i < 24; i++){
scanf("%d", gCell + i);
}
Solve(); }
return 0;
}

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. 利用JDK动态代理机制实现简单拦截器

    利用JDK动态代理机制实现简单的多层拦截器 首先JDK动态代理是基于接口实现的,所以我们先定义一个接口 public interface Executer { public Object execut ...

  2. for语句联系 -小九九乘法表

    public class a { /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 int ...

  3. PHP程序员的10个有用的技巧和教程

    PHP被定义为一个通用的服务器端脚本语言,它基本上是专为Web开发的重要目的.借助PHP可以创建动态和惊人的网页效果,他是被嵌入在一个HTML源文件的服务器端的脚本语言之一.因此,它成为最流行的,也是 ...

  4. DataTables 表格固定栏使用方法

    有时候数据过多,为了用户体验,需要将重要的栏目固定不动,如下图所示: 从上图我们可以看出,表格滚动的时候,左边5栏是不动的.现在说一下实现方法: 插件地址: https://datatables.ne ...

  5. Droptiles - 炫酷的 Metro 风格的层叠式 Web 面板

    介绍 Droptiles是一套Metro风格的类似Win8的Web2.0控制面板.它采用图块(tiles)建立用户体验.图块(tiles)是一些可以从外部资源中获取数据的迷你应用.点击图块(tile) ...

  6. latex之转置符号

    $\mathbf{A}^\mathrm{T}$ $\mathbf{A}^\top$ $\mathbf{A}^\mathsf{T}$ $\mathbf{A}^\intercal$ 效果分别为:

  7. ubuntu12.04开启虚拟机的unity模式

    终端中输入: sudo add-apt-repository ppa:gnome3-team/gnome3 sudo apt-get update sudo apt-get install gnome ...

  8. The configuration file 'appsettings.json' was not found and is not optional

    问: .Net Core: Application startup exception: System.IO.FileNotFoundException: The configuration file ...

  9. 一个窗口里包含一个iframe,点击iframe内的submit按钮,返回的视图总是显示在iframe中,我想要的效果是点击按钮后返回的视图是在浏览器窗口中...?asp.net mvc 的action中,不用js怎么实现??????????

    Content("<script type='text/javascript'>parent.location.href = '" + url + "';&l ...

  10. 解析oracle的rownum

    本人最近在使用oracle的rownum实现分页显示的时候,对rownum做了进一步的分析和研究.现归纳如下,希望能给大家带来收获. 对于rownum来说它是oracle系统顺序分配为从查询返回的行的 ...