zoukankan      html  css  js  c++  java
  • 洛谷 P1379 八数码难题

    洛谷 P1379 八数码难题

    洛谷传送门

    JDOJ 1461: VIJOS-P1360 八数码问题

    JDOJ传送门

    Description

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

    Input

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

    Output

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

    Sample Input

    283104765

    Sample Output

    4


    最优解声明:


    题解:

    双向BFS+map去重。

    这里采用了把序列化成矩阵的模式,方便继续往下搜。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<map>
    #include<queue>
    #define ll long long int
    using namespace std;
    int n,g=123804765;
    int a[4][4],fx,fy,nx,ny;
    int dx[4]={1,-1,0,0};
    int dy[4]={0,0,1,-1};
    queue<int> q;
    map<int,int> v,ans;
    int main()
    {
        scanf("%d",&n);
    	if(n==g)
        {
            printf("0");
            exit(0);
        }				
        q.push(n);
        q.push(g);
        ans[n]=0;
        ans[g]=1;		
        v[g]=2;
        v[n]=1;
        while(!q.empty())
        {
            ll now,cur=q.front();
            q.pop();
            now=cur;
            for(int i=3;i>=1;i--)
                for(int j=3;j>=1;j--)
                {
                    a[i][j]=now%10,now/=10;
                    if(a[i][j]==0) fx=i,fy=j;
                }
            for(int i=0;i<4;i++)
            {
                nx=fx+dx[i];
                ny=fy+dy[i];
                if(nx<1 || nx>3 || ny<1 || ny>3) 
    				continue;
                swap(a[fx][fy],a[nx][ny]);
                now=0;
                for(int p=1;p<=3;p++)
                    for(int j=1;j<=3;j++)
                        now=now*10+a[p][j];
                if(v[now]==v[cur]) 
                {
                    swap(a[fx][fy],a[nx][ny]);
                    continue;
                }
                if(v[now]+v[cur]==3)
                {
                    printf("%d",ans[cur]+ans[now]);
                    exit(0);
                }
                ans[now]=ans[cur]+1;
                v[now]=v[cur];
                q.push(now);
                swap(a[fx][fy],a[nx][ny]);
            }	
        }
    }
    
  • 相关阅读:
    利用世界杯,读懂 Python 装饰器
    利用python开发app实战
    Python协程(真才实学,想学的进来)
    Python 中的 10 个常见安全漏洞,以及如何避免(上)
    Python学到什么程度才可以去找工作?掌握这4点足够了!
    Hadoop Yarn调度器的选择和使用
    CSS 预处理器 Stylus分享
    我想写小说了怎么回事...
    新随笔-- from笔试
    我是不是有点胖了
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13854088.html
Copyright © 2011-2022 走看看