zoukankan      html  css  js  c++  java
  • 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
    %d
    ",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;
    }
    View Code

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

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

  • 相关阅读:
    第一个mpvue小程序开发总结
    ES6学习笔记(一)——扩展运算符和解构赋值
    我所理解的发布订阅模式
    移动web开发适配方案之Rem
    探究JS中对象的深拷贝和浅拷贝
    《BAT前端进阶[师徒班]》学习总结
    浅析使用vue-router实现前端路由的两种方式
    webpack之proxyTable设置跨域
    《免费前端教程不会告诉你这些》知乎LIVE读后感
    MySQL binlog-server搭建
  • 原文地址:https://www.cnblogs.com/acboyty/p/9595341.html
Copyright © 2011-2022 走看看