P1379 八数码难题

原题链接

题解1:朴素广搜

注意细节

code1

#include<bits/stdc++.h>
using namespace std;
int poi[4]={-3,1,-1,3};
int main()
{
    string s;
    cin>>s;
    queue<string> q;
    map<string,int> rec;
    q.push(s);
    rec[s]=1;
    while(q.size())
    {
        string now=q.front();
        q.pop();
        if(now=="123804765")break;
        for(int i=0;i<9;i++)
        if(now[i]=='0')
        {
            for(int j=0;j<4;j++)
            {
                int id=i+poi[j];
                if(id<0||id>8||id==2&&i==3||id==3&&i==2||id==5&&i==6||id==6&&i==5)continue;//注意细节,如果位于矩阵边缘就不能进行某些操作!!
                string next=now;
                swap(next[i],next[id]);
                if((rec[next]>rec[now]+1||!rec[next])&&(rec[next]=rec[now]+1)) q.push(next);
            }
            break;
        }
    }


    cout<<rec["123804765"]-1;
    return 0;
}

题解2

A*搜索,其实在我看来像是一种贪心,通过预估函数预估走这个节点到达终点需要的花费和已经花费的,然后按花费从小到大排序,优先遍历小的
由于本题数据较小,所以这里优先遍历能通过的,再因为本题数据较小,所以预估能到达的都遍历
又因为迭代深度达到一定时就一定可以到达,所以二分深度,然后贪心深搜(因为深度一定,快速达到深度,比广搜更高效)

code2

#include<bits/stdc++.h>
using namespace std;
int xx[4]={1,0,-1,0},yy[4]={0,1,0,-1};
string raw="123804765";
string s;
int dif()
{
    int ans=0;
    for(int i=0;i<9;i++)
    {
        if(s[i]=='0') continue;
        int pos=raw.find(s[i]);
        int x=i/3,y=i%3;
        int x1=pos/3,y1=pos%3;
        ans+=abs(x-x1)+abs(y-y1);
    }
    return ans;
}

int depth;
int ss(int sum,int fa)
{
    int dif1=dif();
    if(dif1==0)return 1;
    if(sum+dif1>depth)return 0;
    int pos=s.find('0');
    int x=pos/3,y=pos%3;;
    for(int i=0;i<4;i++)
    {
        int x1=x+xx[i],y1=y+yy[i];
        if(x1>2||x1<0||y1>2||y1<0) continue;
        int pos1=x1*3+y1;
        if(pos1==fa) continue;
        swap(s[pos],s[pos1]);
        int re=ss(sum+1,pos);
        swap(s[pos],s[pos1]);
        if(re)return 1;
    }
    return 0;
}
int main()
{
    cin>>s;
    int l=-1,r=27;
    while(l<r-1)
    {
        depth=(l+r)/2;
        if(ss(0,-1)) r=depth;
        else l=depth;
    }
    cout<<r;

    return 0;
}
posted @   纯粹的  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示