Solve 3*3 puzzle with C++.

Posted by Graxeon on Thu, 18 Jun 2020 18:05:58 +0200

Puzzle problem

In a 3*3 puzzle, how to spell it with the least steps is a shortest path problem, which can be solved by using BFS. Each node is a state, and then the least steps are obtained. The intermediate state may require encoding or hashing records for each state to be output. This code only solves the problem of minimum steps. In fact, printing can be achieved by using a stack.The process of solving a problem.

Code

#include<bits/stdc++.h> 
using namespace std;

typedef int State[9];
const int maxstate=1000000;
State st[maxstate],goal;
int dist[maxstate];

const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
int vis[362880],fact[9];

void init_lookup_table(){
    fact[0]=1;
    for(int i=1;i<9;i++)    fact[i]=fact[i-1]*i;
}
int try_to_insert(int s){
    int code=0;
    for(int i=0;i<9;i++){
        int cnt=0;
        for(int j=i+1;j<9;j++)  if(st[s][j]<st[s][i])   cnt++;
        code+=fact[8-i]*cnt;
    }
    if(vis[code])   return 0;
    return vis[code]=1;
}
int bfs(){
    init_lookup_table();
    int front=1,rear=2;
    while(front<rear){
        State& s=st[front];
        if(memcmp(goal,s,sizeof(s))==0) return front;
        int z;
        for(z=0;z<9;z++)    if(!s[z])   break;
        int x=z/3, y=z%3;
        for(int d=0;d<4;d++){
            int newx=x+dx[d];
            int newy=y+dy[d];
            int newz=newx*3+newy;
            if(newx>=0&&newx<3&&newy>=0&&newy<3){
                State& t=st[rear];
                memcpy(&t,&s,sizeof(s));
                t[newz]=s[z];
                t[z]=s[newz];
                dist[rear]=dist[front]+1;
                if(try_to_insert(rear)) rear++;
            }
        }
        front++;
    }
    return 0;
}
int main(){
    freopen("F://inp.txt","r",stdin);
    for(int i=0;i<9;i++)    cin>>st[1][i];
    for(int i=0;i<9;i++)    cin>>goal[i];
    for(int i=0;i<9;i++){if(i&&i%3==0)  cout<<endl;cout<<st[1][i]<<" ";}
    int ans=bfs();
    if(ans>0)   printf("\nNeed %d steps come out!\n",dist[ans]);
    else    printf("\nNo way!\n");
    for(int i=0;i<9;i++){if(i&&i%3==0)  cout<<endl;cout<<goal[i]<<" ";}
    return 0;
}

Topics: encoding