题目大意

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

题目分析

要求最少需要几步到达结果,可以考虑广度优先搜索算法,或者迭代加深深度优先搜索(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. Ubuntu 16.04使用git

    Ubuntu 16.04安装git 安装完RabbitVCS之后,Android studio里git还是没法用,找不到git程序,git命令也找不到,说明没有安装git! sudo apt-get ...

  2. elasticsearch安装与使用(6)-- Logstash安装与配置

    由于elasticsearch的search guard 不支持 elasticsearch的jdbc,所以如果安装了search guard认证插件之后,基本上jdbc就废了,所以我们需要用到log ...

  3. Mysql 常用工具

    mysqladmin:用于管理MySQL服务器的客户端 mysqladmin是一个执行管理操作的客户程序.可以用它来检查服务器的配置和当 前的状态,创建并删除数据库等等. 这样调用mysqladmin ...

  4. kettle启动时候报a fatal exception has occurred

    本人刚接触ETL工具 Data Integration - Kettle ,下载了kettle6.0版本,但是在window +jdk1.7(32位)下启动报错, 使用SpoonDebug.bat写的 ...

  5. JQuery下拉控件select的操作汇总

    JQuery获取和设置Select选项方法汇总如下: 获取select 先看看下面代码:   $("#select_id").change(function(){//code... ...

  6. MongoDB 常用shell命令汇总

    //指定用户名和密码连接到指定的MongoDB数据库 mongo 192.168.1.200:27017/admin -u user -p password use youDbName 1.Mongo ...

  7. 在安装ZooKeeper之前,请确保你的系统是在以下任一操作系统上运行

    在安装ZooKeeper之前,请确保你的系统是在以下任一操作系统上运行: 任意Linux OS - 支持开发和部署.适合演示应用程序. Windows OS - 仅支持开发. Mac OS - 仅支持 ...

  8. nodejs基础 -- 事件循环

    Node.js 事件循环 Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用, ...

  9. 转载: Erlang Socket解析二进制数据包

    转自:http://www.itkee.com/developer/detail-318.html 今天在家里闲来无事,实践了一下Erlang的Socket的功能.记录一下在过程中遇到的一些问题,以及 ...

  10. Mysql利用match...against进行全文检索

    在电商项目中,最核心的功能之一就是搜索功能,搜索做的好,整个电商平台就是个优秀的平台.一般搜索功能都使用搜索引擎如Lucene.solr.elasticsearch等,虽然这功能比较强大,但是对于一些 ...