• 【洛谷】P1379 八数码难题(bfs)


    题目

    题目描述

    在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

    输入输出格式

    输入格式:
    输入初始状态,一行九个数字,空格用0表示

    输出格式:
    只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

    输入输出样例

    输入样例#1:
    283104765
    输出样例#1:
    4


    分析

    对着lrj紫书瞎改改,就A了。


    代码

    #include<cstdio>
    #include<cstring>
    #include<set>
    using namespace std;
    
    typedef int State[9];
    const int MAXSTATE=1000000;
    State st[MAXSTATE],goal={1,2,3,8,0,4,7,6,5};
    int dist[MAXSTATE];
    
    set<int> vis;
    void init_lookup_table() { vis.clear(); }
    int try_to_insert(int s)
    {
        int v=0;
        for(int i=0;i<9;i++) v=v*10+st[s][i];
        if(vis.count(v)) return 0;
        vis.insert(v);
        return 1;
    }
    
    const int dx[]={-1,1,0,0};
    const int dy[]={0,0,-1,1};
    int bfs()
    {
        init_lookup_table();
        int front=1,rear=2;
        while(front<rear)
        {
            State& s=st[front];
            if(memcmp(goal,s,sizeof(s))==0) return front;
            int z;
            for(z=0;z<9;z++) if(!s[z]) break;
            int x=z/3,y=z%3;
            for(int d=0;d<4;d++)
            {
                int newx=x+dx[d];
                int newy=y+dy[d];
                int newz=newx*3+newy;
                if(newx>=0 && newx<3 && newy>=0 && newy<3)
                {
                    State& t=st[rear];
                    memcpy(&t,&s,sizeof(s));
                    t[newz]=s[z];
                    t[z]=s[newz];
                    dist[rear]=dist[front]+1;
                    if(try_to_insert(rear)) rear++;
                }
            }
            front++;
        }
        return 0;
    }
    
    int main()
    {
        char s[15];
        scanf("%s",s);
        for(int i=0;i<9;i++)
            st[1][i]=s[i]-'0';
    //	for(int i=0;i<9;i++) printf(" %d ",st[1][i]); 
        int ans = bfs();
        printf("%d
    ", dist[ans]);
        return 0;
    }
    
  • 相关阅读:
    使用工具自动生成Linq类文件
    DateTime.MinValue和MaxValue引发的异常
    C# AD 验证登陆
    HttpWebRequest的GetResponse或GetRequestStream偶尔超时 + 总结各种超时死掉的可能和相应的解决办法
    清理sqlserver 2012 日志文件
    如何修改博客园插入代码的默认代码大小?
    hdu 1241:Oil Deposits(DFS)
    【2014年寒假日常记录表(2014.1.9—2.23,45天)】
    hdu 1016 Prime Ring Problem(DFS)
    蓝桥杯 历届试题 错误票据(水题,排序)
  • 原文地址:https://www.cnblogs.com/noblex/p/8047025.html
Copyright © 2020-2023  润新知