马走棋盘到八数码问题的解决(BFS法)

BFS法:

从我们最开始的地方开始遍历,一开始将这个初始位置放在一个队列里面,然后开始遍历这个队列,从初始位置开始将可以到达的状态保存在队列里面,直到没有状态可以到达的时候,我们就将这个初始位置弹出队列,然后在进行队列遍历直到我们找到答案位置。(每次判断该次状态是否之前有达到过)

1、马走棋盘
  问题描述:在一个n*m的棋盘上,给出马的初始位置,然后看棋盘上的位置马最少走几步可以到达,然后输出棋盘上马可以到达最少次数的矩阵,如果不可以到达则改点位置为-1;

  解题思路:这里我看到是最少到达步数,所以考虑到了BFS来解决最少问题,这里就可以对马的位置进行BFS遍历。

  代码解决:

#include<iostream>
#include<queue>
using namespace std;
int xx[]={1,2,1,2,-1,-2,-1,-2};//马可以的八个方向
int yy[]={2,1,-2,-1,2,1,-2,-1};
int chessboard[10][10];//定义的棋盘
int vis[10][10];//用来记录棋盘的每个位置是否走过
queue<int> a;//定义队列因为有x,y两个数据定义两个,这里可以采用结构体
queue<int> b;
int pd(int x,int y)//判断是否超出棋盘,这里我是从1,1开始接受数据的
{
    if(x<=3&&x>=1&&y<=3&&y>=1)
    {
        return 1;
    }
    return 0;
}
void bfs(int x,int y)
{
        chessboard[x][y]=0;
        vis[x][y]=1;
        a.push(x);
        b.push(y);
        while(!a.empty())
        {
            
            int sx=a.front();
            int sy=b.front();
               for(int i=0;i<8;i++)
               {
                  int  x1=sx+xx[i];
                  int y1=sy+yy[i];
                   if(pd(x1,y1)==1&&vis[x1][y1]==0)//判断位置是否在棋盘上和棋盘上该位置是否遍历了,
                   {
                       chessboard[x1][y1]=chessboard[sx][sy]+1;//该位置的步数为之前位置加1即可!
                       vis[x1][y1]=1;
                       a.push(x1);
                       b.push(y1);
                   }

               }
              a.pop();
              b.pop();
        }

}
int main()
{

     int n,m,x,y;
     cin>>n>>m>>x>>y;
     for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
               chessboard[i][j]=-1;//初始化棋盘
               vis[i][j]=0;
        }
      bfs(x,y);
     for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
              cout<<chessboard[i][j]<<' ';
        }
        cout<<endl;
    }

    return 0;
}

2、八数码问题

2 0 3             1 2 3
1 8 4 ------------------------》 8 0 4
7 6 5             7 6 5

将例如左边的状态通过移动转化到右边的状态;(0代表空格)

解题思路:这道题我把空格看做可以和周围其他数字进行交换的,对空格初始的位置进行BFS,然后知道我们找到答案位置,这里我是将每次得到的状态保存在三位数组里面,后面也会用来遍历是否当前状态是否在之前的状态之中;

代码

#include<iostream>
#include<queue>
#include<stdio.h>
using namespace std;
int xx[]={0,1,0,-1};//为可以移动的四个方向
int yy[]={1,0,-1,0};
int chessboard[1000001][4][4];//用来保存每次移动到达状态
int top=0,top1=0;
int num[100][4],tt=0;//用来保存从一个状态可以达到的其它状态比如num[0][1]=2说明从0即初始状态可到达
queue<int> a;           //2状态;
queue<int> b;
int pd(int x)//判断是否到达目标状态
{
    if(chessboard[x][1][1]==1&&chessboard[x][1][2]==2&&chessboard[x][1][3]==3
       &&chessboard[x][2][3]==4&&chessboard[x][3][3]==5&&chessboard[x][3][2]==6
       &&chessboard[x][3][1]==7&&chessboard[x][2][1]==8)
        return 1;
    return 0;
}
int wzpd(int x,int y)//判断是否在棋盘上
{
    if(x>=1&&x<=3&&y>=1&&y<=3)
    {
        return 1;
    }
    return 0;
}

int cf(int chess[4][4])//检查当前状态是否在之前有过的状态之中
{

    for(int x=0;x<=top1;x++)
    {
        int flag=1;
        for(int i=1;i<=3;i++)
        {
            for(int j=1;j<=3;j++)
            {
                if(chessboard[x][i][j]==chess[i][j])
                {
                    flag=1;
                }
                else
                {
                    flag=0;
                    goto loop;
                }
            }
        }
        if(flag==1)
        {
            return 0;
        }
        loop:;
    }
    return 1;
}
void BFS(int h,int g)//开始进行BFS遍历
{
    a.push(h);
    b.push(g);
    while(!a.empty())
    {

        int x=a.front();
        int y=b.front();
        for(int i=0;i<4;i++)
        {
            int x1=x+xx[i];
            int y1=y+yy[i];
            if(wzpd(x1,y1)==1)
            {

                int chess1[4][4];
                for(int k=1;k<=3;k++)
                   {
                       for(int l=1;l<=3;l++){

                       chess1[k][l]=chessboard[top][k][l];

                     }

                   }
                   for(int k=1;k<=3;k++)
                   {
                       for(int l=1;l<=3;l++){

                       cout<<chess1[k][l]<<' ';


                     }
                     cout<<endl;

                   }
                int temp;
                temp=chess1[x][y];
                chess1[x][y]=chess1[x1][y1];
                chess1[x1][y1]=temp;
                if(cf(chess1)==1)
                {
                  cout<<"选择第"<<top<<"个来进行扩展"<<endl;

                for(int u=1;u<=3;u++)
                {
                    for(int c=1;c<=3;c++)
                    {
                        cout<<chess1[u][c]<<' ';
                    }
                    cout<<endl;
                }
                top1++;
                num[tt][i]=top1;
                for(int q=1;q<=3;q++)
                  {
                      for(int p=1;p<=3;p++)
                     {
                        chessboard[top1][q][p]=chess1[q][p];


                    }
                    cout<<endl;

                  }
                      if(pd(top1)==1)
                    {

                       return ;
                    }

                 a.push(x1);
                 b.push(y1);

                }
                else
                {
                    cout<<"*******************已经存在了**********"<<endl;
                }
            }

        }
        a.pop();
        b.pop();
        top++;
        tt++;
    }
}
int main()
{

     int stratx,straty;
     for(int i=1;i<=3;i++)
     {
         for(int j=1;j<=3;j++)
         {
             cin>>chessboard[0][i][j];
             if(chessboard[0][i][j]==0)
             {
                 stratx=i;
                 straty=j;
             }
         }
     }

     BFS( stratx, straty);
      int lj[100],kk=2;
      lj[0]=top1;
      lj[1]=top;
      while(top!=0)
      {
            for(int i=0;i<=top;i++)
        {


            for(int j=0;j<4;j++)
            {
                  if(num[i][j]==top)
                  {
                      lj[kk++]=i;
                      top=i;
                      if(top==0)
                      {
                          goto loop;
                      }

                  }
            }

          }
      }
      loop:;
      int step=1;
      cout<<endl<<endl<<"开始:"<<endl;
      for(int i=kk-1;i>=0;i--)
      {

          for(int x=1;x<=3;x++)
          {
              for(int y=1;y<=3;y++)
              {
                  cout<<chessboard[lj[i]][x][y]<<' ';
              }
              cout<<endl;
          }
          cout<<endl;
          if(i!=0)
          {
              cout<<"第"<<step++<<"步"<<':'<<endl;
          }
          //cout<<endl;
      }


}

```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坏牧羊人.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值