1 条题解

  • 0
    @ 2025-8-24 21:24:26

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar hidden_er
    **

    搬运于2025-08-24 21:24:25,当前版本为作者最后更新于2017-11-01 21:42:52,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    上次发过超长代码的题解后惨遭同校大佬批斗

    痛定思痛,在向大佬学习之后,带来最短代码(滑稽)

    思路大体与之前相同:

    map去重,

    在这里只需要一个队列,因为需要较少步数达到的状态一定在步数较多的状态前入队列

    (我之前那个最长程序也可以用一个队列,不需要两个队列辗转,只要加个步数的记录就行了)

    stl大法好%%%

    #include<iostream>
    #include<map>
    #include<queue>
    #include<algorithm>
    #define ll long long//在这里看到一种很骚的操作:直接把int定义成long long;main函数用signed类型--麻麻再也不怕我忘开long long了!
    using namespace std;
    const ll dx[]={-1,0,0,1},dy[]={0,-1,1,0};//转移数组;
    ll n;
    int  main()
    {
        cin>>n;
        queue<ll> q;
        q.push(n);
        map<ll,ll> m;
        m[n]=0;
        while(!q.empty())
        {
            int u=q.front(); //初始状态入队列
            int c[3][3],f=0,g=0,n=u;q.pop();
            if(u==123804765)break;
            for(ll i=2;i>=0;i--)
                for(ll j=2;j>=0;j--)
                {
                    c[i][j]=n%10,n/=10;
                    if(!c[i][j])f=i,g=j;
                }
            for(ll i=0;i<4;i++)
            {
                ll nx=f+dx[i],ny=g+dy[i],ns=0;
                if(nx<0||ny<0||nx>2||ny>2)continue; //越界就不执行
                swap(c[nx][ny],c[f][g]);
                for(ll i=0;i<3;i++)
                    for(ll j=0;j<3;j++)ns=ns*10+c[i][j];//矩阵转数列 
                if(!m.count(ns))
                {
                    m[ns]=m[u]+1;//map去重的同时顺便统计到达这个状态所需的步数
                    q.push(ns);
                }
                swap(c[nx][ny],c[f][g]);//状态复原
            }
        }
        cout<<m[123804765]<<endl; // map的下标直接用数列表示
        return 0;
    }
    
    
    • 1

    信息

    ID
    376
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者