用C++来解决3*3拼图

来源:互联网 发布:淘宝内衣女模特叫名字 编辑:程序博客网 时间:2024/05/02 00:54

拼图问题

在3*3的拼图中,如何用最少步骤拼好它,这个问题是一个最短路径问题,可以使用BFS来求解,每个节点是一个状态,然后得到最少步骤,中间状态可能需要对每一个状态进行编码或者散列记录才能输出,本代码只解决了求最短步数,其实利用一个栈是可以实现打印解题过程的。

代码

#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;}
原创粉丝点击