八数码难题

本文介绍了解决八数码问题的一种简单方法,通过广度优先搜索(BFS)找到从初始状态到目标状态的最短路径。使用了 set 数据结构进行判重,避免重复搜索已遍历的状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天做了一道八数码,完全没有bfs的思路,还是请大佬点通了以下,才知道这跟bfs没有什么区别

八数码难题

之所以要把难题划掉,是因为发现这根本是一道题,对,没错,没有你想的那么难

解题思路

首先给你的一个数,就是八数码的排列,也就是\(0\sim8\)的全排列,然后你需要搜索他怎样移动。
然后我们需要判重了,判重的方法有很多,可以用hash,但是你取模药珂学。

然后这就是hash冲突的惨案
1404540-20180911104412879-337478545.png
1404540-20180911104434319-83770222.png

然后就是代码了,这里判重我用的set

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
using namespace std;
set<int>s;
const int TOM = 123804765;
struct edge
{
    int x,y,dis,id;
    edge(){};
    edge(int a,int b,int c,int d){x=a,y=b,id=c,dis=d;}
}e[100];
queue<edge>q;
int n;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int num[4][4],tx,ty;
int main(){
    int fi=0;
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++){
            int a;
            scanf("%1d",&a);
            fi=fi*10+a;
            if(a==0)tx=i,ty=j;  
        }   
    q.push(edge(tx,ty,fi,0));
    s.insert(fi);
    if(fi==TOM){
        printf("0");
        return 0;
    }
    while(!q.empty()){
        edge u=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int xx=dx[i]+u.x;
            int yy=dy[i]+u.y;
            if(xx<1||xx>3||yy<1||yy>3)continue;
            memset(num,0,sizeof(num));
            int k=u.id;
            for(int i=3;i>=1;i--)
                for(int j=3;j>=1;j--)
                    num[i][j]=k%10,k/=10;
            num[u.x][u.y]=num[xx][yy];
            num[xx][yy]=0;
            k=0;
            for(int i=1;i<=3;i++)
                for(int j=1;j<=3;j++)
                    k=k*10+num[i][j];
            if(!s.count(k)){
                s.insert(k);
                q.push(edge(xx,yy,k,u.dis+1));
            }
            if(k==TOM){
                printf("%d",u.dis+1);
                return 0;
            }
        }
    }
}

转载于:https://www.cnblogs.com/ifmyt/p/9626229.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值