八数码难题

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

八数码难题

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

解题思路

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

然后这就是hash冲突的惨案

然后就是代码了,这里判重我用的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