hdu 1667 The Rotation Game ( IDA* )

题目大意:

给你一个“井”子状的board,对称的由24个方块组成,每个方块上有123三个数字中的一个。给你初始状态,共有八种变换方式,求字典序最小的最短的的变换路径使得,board中间的八个方块上数字相同。(建议看下题目中的图就懂啦)。

IDA*搜索。

我是干脆用结构体保存搜索状态(当然这样很占空间了,可能也耗时间,不过这题15s/150M的时空限制我也是醉了)。保存一个board temp,一个搜索路径path,搜索深度n,以及一个内置的估值函数h()。h()返回的是8减这八个方块上出现最多的数字的次数,因为一次变换只能改变一个数字的个数,所以h()是比实际小的,满足A*条件。接下来就是迭代dfs搜索了。设置一个初值为0的max,当h()时,表示搜到目标,打印然后return true;若n+h()<=max(这其实就是A*的剪枝思想了),往下向八个方向搜索(用数组dir保存)。若有一个方向成功,则return true;都没成功返回false。max反复++,直至搜到答案。

个人觉得ida*比a*的题目要好写呢。。果然dfs比bfs要友善很多啊。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>

using namespace std;

int board[24];
int aim[8]={6,7,8,11,12,15,16,17};
//8个方向,比下标大1
int dir[8][7]= {1,3,7,12,16,21,23,
                2,4,9,13,18,22,24,
                11,10,9,8,7,6,5,
                20,19,18,17,16,15,14,
                24,22,18,13,9,4,2,
                23,21,16,12,7,3,1,
                14,15,16,17,18,19,20,
                5,6,7,8,9,10,11
               };
char diralpha[9]="ABCDEFGH";

struct tnode
{
    int temp[24];
    string path;
    int n;
    inline int h()
    {
        int a=0,b=0,c=0;
        for(int i=0;i<8;i++)
        {
            if(temp[aim[i]]==1)
                a++;
            else if(temp[aim[i]]==2)
                b++;
            else
                c++;
        }
        return 8-max(a,max(b,c));
    }
};

bool dfs(int mmax,tnode x)
{
    if(x.h()==0)
    {
        if(x.n==0)
            printf("No moves needed\n%d\n",x.temp[aim[0]]);
        else
            cout<<x.path<<endl<<x.temp[aim[0]]<<endl;
        return true;
    }
    if(x.n+x.h()<=mmax)
    {
        tnode y;
        for(int i=0;i<8;i++)
        {
            y=x;
            y.path+=diralpha[i];
            y.n++;
            for(int j=0;j<7;j++)
                y.temp[dir[i][j]-1]=x.temp[dir[i][(j+1)%7]-1];
            if(dfs(mmax,y))
                return true;
        }
    }
    return false;
}

int main()
{
    while(scanf("%d",board),board[0])
    {
        for(int i=1;i<24;i++)
            scanf("%d",board+i);

        tnode st;
        memcpy(st.temp,board,sizeof(board));
        st.n=0;
        st.path="";
        for(int i=0,flag=false;flag==false;i++)
        {
            flag=dfs(i,st);
        }
    }
    return 0;
}

PS:某学长想用3进制数判重写,然后MLE了无数发。。(?)所以之后要不要考虑自己也作死一发呢。

PS2:最近没怎么更新博客。。也是比较颓,没有好好学习,好好做题(愧疚)。今天算是好好学习了一天吧。。但愿能够坚持下去。。Keep going and never give up!

原文地址:https://www.cnblogs.com/acboyty/p/9595341.html

时间: 2024-11-08 15:41:21

hdu 1667 The Rotation Game ( IDA* )的相关文章

HDU 1667 The Rotation Game (A*迭代搜索)

题目大意:略 每次选择一个最大深度K,跑IDA* 估价函数H=8-中间8个格里出现次数最多的数的个数x,即把它填满这个数最少需要8-x次操作,如果dep+H>K,就跳出.. 深搜的时候暴力修改,记录操作的方向,回溯再改回来就行了,根本不用把网格压进状态里嘛.. 又水了一篇博客 #include <queue> #include <cstdio> #include <cstring> #include <algorithm> #define NN 201

[poj2286]The Rotation Game (IDA*)

//第一次在新博客里发文章好紧张怎么办 //MD巨神早已在一个小时前做完了 The Rotation Game Time Limit: 15000MS Memory Limit: 150000K Total Submissions: 5950 Accepted: 1992 Description The rotation game uses a # shaped board, which can hold 24 pieces of square blocks (see Fig.1). The b

【HDOJ】1667 The Rotation Game

1. 题目描述有个#字型的条带,可以从横线或竖线进行循环移动,求通过各种移动最终使中心的8个字符全等的长度最短并相同长度字典序最小的操作序列.2. 基本思路24个数据,8种移动方式,数据量很小了,所以基本怎么玩儿都可以.需要注意的是因为横线竖线间有交点,所以每个条带的数据可能都是变化的.采用IDA*算法可解.所谓IDA*,就是不断对所求操作需要长度进行增加,然后不断当前长度是否存在可行的操作序列.判断是否存在可行操作序列的方法是深搜,这里需要注意去除先移动A紧接着移动F的类似情况.H函数的基本想

HDU 1560 DNA sequence(IDA*)

DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6042    Accepted Submission(s): 2735 Problem Description The twenty-first century is a biology-technology developing century. We kno

UVa1603 The Rotation Game (IDA*)

链接:http://acm.hust.edu.cn/vjudge/problem/36627分析:感觉这题前面的处理比较麻烦.首先把图中的位置从左到右从上到下编号,然后用一个二维数组记录8个方向上各个位置的编号,枚举最大深度maxd,乐观估计函数为至少需要移动次数,因为每次移动最多改变一个位置上的数字,所以中间8个位置除了出现次数最多的数字外的数字个数为x的话那么就至少要移动x次,枚举move8个方向再递归如果check为true则成功找到解返回,否则将a复位继续枚举,枚举完8个方向找不到解则失

UVa 1343 The Rotation Game(IDA*)

主要是设计乐观估计函数来减枝 假设中心区域有6个2,2个3,那肯定是消掉3最好,毕竟就两个. 那么理想情况下,旋转一次就能把一个3变成2,那么最少操作2次. 我们用h()来计算最少还要操作几次,其原理是假设中心区域都放1或2或3,返回至少操作的次数中最小的数 maxd是假设最多能操作的数; d是已经操作的数; 那么就可以得出乐观估计函数   h()+d>maxd 其含义为 : 若  至少还要操作次数  加上  已经操作的次数  大于  最多总共操作的次数就退出 . 其次就是节点的处理了,编个号数

HDU 专题分类

[背包问题] 2602 Bone Collector 1114 Piggy-Bank 1203 I NEED A OFFER! 1171 Big Event in HDU 1059 Dividing 2844 Coins 2191 悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 2159 FATE 1561 The more, The Better 1011 Starship Troopers 2639 Bone Collector II 3033 I love sneakers! 2955

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

POJ - 2286 - The Rotation Game (IDA*)

IDA*算法,即迭代加深的A*算法,实际上就是迭代加深+DFS+估价函数 题目传送:The Rotation Game AC代码: #include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bitset> #include